diff options
Diffstat (limited to 'gr-qtgui')
-rw-r--r-- | gr-qtgui/Makefile.am | 11 | ||||
-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/Makefile.am | 1 | ||||
-rw-r--r-- | gr-qtgui/grc/qtgui_sink_x.xml | 10 | ||||
-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) | 1 | ||||
-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) | 38 | ||||
-rw-r--r-- | gr-qtgui/lib/Makefile.am (renamed from gr-qtgui/src/lib/Makefile.am) | 50 | ||||
-rw-r--r-- | gr-qtgui/lib/SpectrumGUIClass.cc (renamed from gr-qtgui/src/lib/SpectrumGUIClass.cc) | 130 | ||||
-rw-r--r-- | gr-qtgui/lib/SpectrumGUIClass.h (renamed from gr-qtgui/src/lib/SpectrumGUIClass.h) | 49 | ||||
-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) | 50 | ||||
-rw-r--r-- | gr-qtgui/lib/WaterfallDisplayPlot.h (renamed from gr-qtgui/src/lib/WaterfallDisplayPlot.h) | 30 | ||||
-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) | 0 | ||||
-rw-r--r-- | gr-qtgui/lib/qtgui_sink_c.cc (renamed from gr-qtgui/src/lib/qtgui_sink_c.cc) | 48 | ||||
-rw-r--r-- | gr-qtgui/lib/qtgui_sink_c.h (renamed from gr-qtgui/src/lib/qtgui_sink_c.h) | 29 | ||||
-rw-r--r-- | gr-qtgui/lib/qtgui_sink_f.cc (renamed from gr-qtgui/src/lib/qtgui_sink_f.cc) | 39 | ||||
-rw-r--r-- | gr-qtgui/lib/qtgui_sink_f.h (renamed from gr-qtgui/src/lib/qtgui_sink_f.h) | 28 | ||||
-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) | 63 | ||||
-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) | 0 | ||||
-rw-r--r-- | gr-qtgui/python/Makefile.am (renamed from gr-qtgui/src/python/Makefile.am) | 9 | ||||
-rw-r--r-- | gr-qtgui/python/__init__.py | 25 | ||||
-rwxr-xr-x | gr-qtgui/python/qa_qtgui.py (renamed from gr-qtgui/src/python/qa_qtgui.py) | 20 | ||||
-rw-r--r-- | gr-qtgui/python/run_tests.in (renamed from gr-qtgui/src/python/run_tests.in) | 0 | ||||
-rw-r--r-- | gr-qtgui/src/.gitignore | 2 | ||||
-rw-r--r-- | gr-qtgui/src/lib/TimeDomainDisplayPlot.h | 65 | ||||
-rw-r--r-- | gr-qtgui/src/lib/qtgui.i | 131 | ||||
-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 (renamed from gr-qtgui/src/lib/Makefile.swig.gen) | 98 | ||||
-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 | 66 | ||||
-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 |
72 files changed, 3120 insertions, 705 deletions
diff --git a/gr-qtgui/Makefile.am b/gr-qtgui/Makefile.am index e794266cb..cc194e4c0 100644 --- a/gr-qtgui/Makefile.am +++ b/gr-qtgui/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2008-2010 Free Software Foundation, Inc. +# Copyright 2008-2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,10 +21,11 @@ include $(top_srcdir)/Makefile.common -SUBDIRS = src -DIST_SUBDIRS = src +SUBDIRS = lib if PYTHON -SUBDIRS += grc -DIST_SUBDIRS += grc +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/grc/Makefile.am b/gr-qtgui/grc/Makefile.am index b3114268c..ccd459a13 100644 --- a/gr-qtgui/grc/Makefile.am +++ b/gr-qtgui/grc/Makefile.am @@ -29,5 +29,6 @@ dist_grcblocks_DATA = \ 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_sink_x.xml b/gr-qtgui/grc/qtgui_sink_x.xml index 7a5f5ec13..8c470a1a5 100644 --- a/gr-qtgui/grc/qtgui_sink_x.xml +++ b/gr-qtgui/grc/qtgui_sink_x.xml @@ -21,7 +21,6 @@ qtgui.$(type.fcn)( $name, \#name $plotfreq, \#plotfreq $plotwaterfall, \#plotwaterfall - $plotwaterfall3d, \#plotwaterfall3d $plottime, \#plottime $plotconst, \#plotconst ) @@ -90,15 +89,6 @@ $(gui_hint()($win))</make> <option><name>Off</name><key>False</key></option> </param> <param> - <name>Plot Waterfall 3D</name> - <key>plotwaterfall3d</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> 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 61b9ca8c1..fc4f8cdfe 100644 --- a/gr-qtgui/src/lib/.gitignore +++ b/gr-qtgui/lib/.gitignore @@ -5,7 +5,6 @@ /qtgui.cc /qtgui.py /WaterfallDisplayPlot.moc.cc -/Waterfall3DDisplayPlot.moc.cc /TimeDomainDisplayPlot.moc.cc /spectrumdisplayform.moc.cc /spectrumdisplayform.ui.h 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 3c22c1397..6689703bc 100644 --- a/gr-qtgui/src/lib/FrequencyDisplayPlot.h +++ b/gr-qtgui/lib/FrequencyDisplayPlot.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 FREQUENCY_DISPLAY_PLOT_HPP #define FREQUENCY_DISPLAY_PLOT_HPP @@ -12,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 @@ -43,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: @@ -71,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 446a07fd0..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 # @@ -20,17 +20,18 @@ # include $(top_srcdir)/Makefile.common -include $(top_srcdir)/Makefile.swig EXTRA_DIST += spectrumdisplayform.ui AM_CPPFLAGS = -I. $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) \ - $(QT_INCLUDES) $(BOOST_CPPFLAGS) $(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 \ @@ -50,11 +51,15 @@ 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=$(QMAKE_SOURCES) @@ -68,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 $@ @@ -85,26 +95,8 @@ QT_MOC_FLAGS=-DQT_SHARED -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LI libgnuradio_qtgui_la_LDFLAGS = $(NO_UNDEFINED) $(BOOST_LDFLAGS) $(LTVERSIONFLAGS) libgnuradio_qtgui_la_LIBADD = \ - $(GNURADIO_CORE_LA) \ - $(BOOST_THREAD_LIB) \ - $(BOOST_DATE_TIME_LIB) \ - -lstdc++ \ + $(GNURADIO_CORE_LA) \ + $(BOOST_THREAD_LIB) \ + $(BOOST_DATE_TIME_LIB) \ + -lstdc++ \ $(QT_LIBS) - - -############################## -# SWIG interfaces and libraries - -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 diff --git a/gr-qtgui/src/lib/SpectrumGUIClass.cc b/gr-qtgui/lib/SpectrumGUIClass.cc index 052730fc2..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 @@ -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 57a749a6a..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,20 +68,20 @@ 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(); @@ -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 a8e5361e7..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 @@ -142,7 +164,7 @@ public: 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 - int ind = time_str.find(" "); + 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)); @@ -194,7 +216,7 @@ protected: 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 - int ind = time_str.find(" "); + 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)); @@ -253,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); @@ -267,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 @@ -279,6 +302,8 @@ WaterfallDisplayPlot::WaterfallDisplayPlot(QWidget* parent) _zoomer->setTrackerPen(c); _UpdateIntensityRangeDisplay(); + + _xAxisMultiplier = 1; } WaterfallDisplayPlot::~WaterfallDisplayPlot() @@ -315,6 +340,8 @@ WaterfallDisplayPlot::SetFrequencyRange(const double constStartFreq, double stopFreq = constStopFreq / units; double centerFreq = constCenterFreq / units; + _xAxisMultiplier = units; + _useCenterFrequencyFlag = useCenterFrequencyFlag; if(_useCenterFrequencyFlag){ @@ -544,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 6b4e978bb..583bf9407 100644 --- a/gr-qtgui/src/lib/WaterfallDisplayPlot.h +++ b/gr-qtgui/lib/WaterfallDisplayPlot.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 WATERFALL_DISPLAY_PLOT_HPP #define WATERFALL_DISPLAY_PLOT_HPP @@ -7,6 +29,7 @@ #include <qwt_plot_zoomer.h> #include <qwt_plot_panner.h> +#include <qtgui_util.h> #include <plot_waterfall.h> #include <highResTimeFunctions.h> @@ -50,10 +73,12 @@ public: 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: @@ -62,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 a11461611..a11461611 100644 --- a/gr-qtgui/src/lib/plot_waterfall.h +++ b/gr-qtgui/lib/plot_waterfall.h diff --git a/gr-qtgui/src/lib/qtgui_sink_c.cc b/gr-qtgui/lib/qtgui_sink_c.cc index 05c7b28d5..7b40dd01d 100644 --- a/gr-qtgui/src/lib/qtgui_sink_c.cc +++ b/gr-qtgui/lib/qtgui_sink_c.cc @@ -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,12 +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; - lock(); // Perform fftshift operation; // this is usually desired when plotting @@ -85,7 +74,7 @@ qtgui_sink_c::qtgui_sink_c (int fftsize, int wintype, buildwindow(); - initialize(use_openGL); + initialize(); } qtgui_sink_c::~qtgui_sink_c() @@ -104,25 +93,14 @@ qtgui_sink_c::forecast(int noutput_items, gr_vector_int &ninput_items_required) } } -void qtgui_sink_c::lock() -{ - d_mutex.lock(); -} - -void qtgui_sink_c::unlock() -{ - d_mutex.unlock(); -} - - 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); } @@ -143,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_mutex)); } @@ -288,8 +262,6 @@ qtgui_sink_c::general_work (int noutput_items, int j=0; const gr_complex *in = (const gr_complex*)input_items[0]; - gruel::scoped_lock lock(d_mutex); - // Update the FFT size from the application fftresize(); windowreset(); diff --git a/gr-qtgui/src/lib/qtgui_sink_c.h b/gr-qtgui/lib/qtgui_sink_c.h index bbf9983b0..b0946885c 100644 --- a/gr-qtgui/src/lib/qtgui_sink_c.h +++ b/gr-qtgui/lib/qtgui_sink_c.h @@ -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; - gruel::mutex d_mutex; - 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 984c2803c..3312b9006 100644 --- a/gr-qtgui/src/lib/qtgui_sink_f.cc +++ b/gr-qtgui/lib/qtgui_sink_f.cc @@ -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,12 +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; - lock(); // Perform fftshift operation; // this is usually desired when plotting @@ -85,7 +74,7 @@ qtgui_sink_f::qtgui_sink_f (int fftsize, int wintype, buildwindow(); - initialize(use_openGL); + initialize(); } qtgui_sink_f::~qtgui_sink_f() @@ -104,18 +93,8 @@ qtgui_sink_f::forecast(int noutput_items, gr_vector_int &ninput_items_required) } } -void qtgui_sink_f::lock() -{ - d_mutex.lock(); -} - -void qtgui_sink_f::unlock() -{ - d_mutex.unlock(); -} - void -qtgui_sink_f::initialize(const bool opengl) +qtgui_sink_f::initialize() { if(qApp != NULL) { d_qApplication = qApp; @@ -138,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_mutex)); } void @@ -283,8 +258,6 @@ qtgui_sink_f::general_work (int noutput_items, int j=0; const float *in = (const float*)input_items[0]; - gruel::scoped_lock lock(d_mutex); - // Update the FFT size from the application fftresize(); windowreset(); diff --git a/gr-qtgui/src/lib/qtgui_sink_f.h b/gr-qtgui/lib/qtgui_sink_f.h index d80a6a198..30db05eea 100644 --- a/gr-qtgui/src/lib/qtgui_sink_f.h +++ b/gr-qtgui/lib/qtgui_sink_f.h @@ -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; - gruel::mutex d_mutex; - 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 9831697ac..5b129c7b5 100644 --- a/gr-qtgui/src/lib/qtgui.h +++ b/gr-qtgui/lib/qtgui_util.h @@ -1,71 +1,50 @@ /* -*- c++ -*- */ /* - * Copyright 2008,2011 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 <gruel/thread.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: - gruel::mutex &d_mutex; +class GR_QTGUI_API QwtDblClickPlotPicker: public QwtPlotPicker +{ public: - qtgui_event(gruel::mutex &mutex) - : QEvent((QEvent::Type)(QEvent::User+101)), - d_mutex(mutex) - { - //nop - } - - void lock() - { - d_mutex.lock(); - } + QwtDblClickPlotPicker(QwtPlotCanvas *); + ~QwtDblClickPlotPicker(); - void unlock() - { - d_mutex.unlock(); - } + 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 604b402c5..604b402c5 100644 --- a/gr-qtgui/src/python/.gitignore +++ b/gr-qtgui/python/.gitignore diff --git a/gr-qtgui/src/python/Makefile.am b/gr-qtgui/python/Makefile.am index 0953a71e5..f1bdf359b 100644 --- a/gr-qtgui/src/python/Makefile.am +++ b/gr-qtgui/python/Makefile.am @@ -22,8 +22,7 @@ include $(top_srcdir)/Makefile.common TESTS = -EXTRA_DIST += run_tests.in \ - qt_digital_window.ui +EXTRA_DIST += run_tests.in if PYTHON TESTS += run_tests @@ -32,12 +31,6 @@ DISTCLEANFILES += run_tests qtguipythondir = $(grpythondir)/qtgui noinst_PYTHON = \ - pyqt_example_f.py \ - pyqt_example.py \ - qt_digital.py \ - qt_digital_window.py \ - usrp2_display.py \ - usrp_display.py \ qa_qtgui.py qtguipython_PYTHON = \ 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/src/python/qa_qtgui.py b/gr-qtgui/python/qa_qtgui.py index fbf0de46e..9cafd4550 100755 --- a/gr-qtgui/src/python/qa_qtgui.py +++ b/gr-qtgui/python/qa_qtgui.py @@ -21,9 +21,7 @@ # from gnuradio import gr, gr_unittest -import qtgui -from PyQt4 import QtGui, QtCore -import sys, sip +import qtgui_swig class test_qtgui(gr_unittest.TestCase): @@ -34,12 +32,16 @@ class test_qtgui(gr_unittest.TestCase): self.tb = None def test01 (self): - pass - # Test to make sure we can instantiate these - #self.qapp = QtGui.QApplication(sys.argv) - #self.qtsnk = qtgui.sink_c(1024, gr.firdes.WIN_BLACKMAN_hARRIS, - # 0, 1, "Test", - # True, True, False, True, True) + # 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__': diff --git a/gr-qtgui/src/python/run_tests.in b/gr-qtgui/python/run_tests.in index 909194752..909194752 100644 --- a/gr-qtgui/src/python/run_tests.in +++ b/gr-qtgui/python/run_tests.in diff --git a/gr-qtgui/src/.gitignore b/gr-qtgui/src/.gitignore deleted file mode 100644 index b336cc7ce..000000000 --- a/gr-qtgui/src/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/Makefile -/Makefile.in diff --git a/gr-qtgui/src/lib/TimeDomainDisplayPlot.h b/gr-qtgui/src/lib/TimeDomainDisplayPlot.h deleted file mode 100644 index 952b5c8cf..000000000 --- a/gr-qtgui/src/lib/TimeDomainDisplayPlot.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef TIME_DOMAIN_DISPLAY_PLOT_HPP -#define TIME_DOMAIN_DISPLAY_PLOT_HPP - -#include <stdint.h> -#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/lib/qtgui.i b/gr-qtgui/src/lib/qtgui.i deleted file mode 100644 index bb64c6ae2..000000000 --- a/gr-qtgui/src/lib/qtgui.i +++ /dev/null @@ -1,131 +0,0 @@ -/* -*- 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 "gnuradio.i" - -%{ -#include "qtgui_sink_c.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, - QWidget *parent=NULL); - -class qtgui_sink_f : public gr_block -{ -private: - friend 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, - 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, - 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); -}; - -#if SWIGGUILE -%scheme %{ -(load-extension-global "libguile-gnuradio-qtgui" "scm_init_gnuradio_qtgui_module") -%} - -%goops %{ -(use-modules (gnuradio gnuradio_core_runtime)) -%} -#endif 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/src/lib/Makefile.swig.gen b/gr-qtgui/swig/Makefile.swig.gen index b7a0f3c07..3659601c3 100644 --- a/gr-qtgui/src/lib/Makefile.swig.gen +++ b/gr-qtgui/swig/Makefile.swig.gen @@ -20,37 +20,37 @@ # Boston, MA 02110-1301, USA. # -# Makefile.swig.gen for qtgui.i +# 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 +## ${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 +## ${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_pythondir_category ?= gnuradio/qtgui -qtgui_pylibdir_category ?= $(qtgui_pythondir_category) -qtgui_pythondir = $(pythondir)/$(qtgui_pythondir_category) -qtgui_pylibdir = $(pyexecdir)/$(qtgui_pylibdir_category) +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_scmlibdir = $(libdir) +qtgui_swig_scmlibdir = $(libdir) # The scm files for the guile modules get installed where ever guile -# is installed, usually /usr/share/guile/site/qtgui +# is installed, usually /usr/share/guile/site/qtgui_swig # FIXME: determince whether these should be installed with gnuradio. -qtgui_scmdir = $(guiledir) +qtgui_swig_scmdir = $(guiledir) ## SWIG headers are always installed into the same directory. -qtgui_swigincludedir = $(swigincludedir) +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 @@ -75,70 +75,70 @@ MOSTLYCLEANFILES += $(DEPDIR)/*.S* ## Makefile.am by setting the variable value there, then including ## Makefile.swig . -qtgui_swiginclude_HEADERS = \ - qtgui.i \ - $(qtgui_swiginclude_headers) +qtgui_swig_swiginclude_HEADERS = \ + qtgui_swig.i \ + $(qtgui_swig_swiginclude_headers) if PYTHON -qtgui_pylib_LTLIBRARIES = \ - _qtgui.la +qtgui_swig_pylib_LTLIBRARIES = \ + _qtgui_swig.la -_qtgui_la_SOURCES = \ - python/qtgui.cc \ - $(qtgui_la_swig_sources) +_qtgui_swig_la_SOURCES = \ + python/qtgui_swig.cc \ + $(qtgui_swig_la_swig_sources) -qtgui_python_PYTHON = \ - qtgui.py \ - $(qtgui_python) +qtgui_swig_python_PYTHON = \ + qtgui_swig.py \ + $(qtgui_swig_python) -_qtgui_la_LIBADD = \ +_qtgui_swig_la_LIBADD = \ $(STD_SWIG_LA_LIB_ADD) \ - $(qtgui_la_swig_libadd) + $(qtgui_swig_la_swig_libadd) -_qtgui_la_LDFLAGS = \ +_qtgui_swig_la_LDFLAGS = \ $(STD_SWIG_LA_LD_FLAGS) \ - $(qtgui_la_swig_ldflags) + $(qtgui_swig_la_swig_ldflags) -_qtgui_la_CXXFLAGS = \ +_qtgui_swig_la_CXXFLAGS = \ $(STD_SWIG_CXX_FLAGS) \ -I$(top_builddir) \ - $(qtgui_la_swig_cxxflags) + $(qtgui_swig_la_swig_cxxflags) -python/qtgui.cc: qtgui.py -qtgui.py: qtgui.i +python/qtgui_swig.cc: qtgui_swig.py +qtgui_swig.py: qtgui_swig.i # Include the python dependencies for this file --include python/qtgui.d +-include python/qtgui_swig.d endif # end of if python if GUILE -qtgui_scmlib_LTLIBRARIES = \ - libguile-gnuradio-qtgui.la -libguile_gnuradio_qtgui_la_SOURCES = \ - guile/qtgui.cc \ - $(qtgui_la_swig_sources) -nobase_qtgui_scm_DATA = \ - gnuradio/qtgui.scm \ - gnuradio/qtgui-primitive.scm -libguile_gnuradio_qtgui_la_LIBADD = \ +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_la_swig_libadd) -libguile_gnuradio_qtgui_la_LDFLAGS = \ + $(qtgui_swig_la_swig_libadd) +libguile_gnuradio_qtgui_swig_la_LDFLAGS = \ $(STD_SWIG_LA_LD_FLAGS) \ - $(qtgui_la_swig_ldflags) -libguile_gnuradio_qtgui_la_CXXFLAGS = \ + $(qtgui_swig_la_swig_ldflags) +libguile_gnuradio_qtgui_swig_la_CXXFLAGS = \ $(STD_SWIG_CXX_FLAGS) \ -I$(top_builddir) \ - $(qtgui_la_swig_cxxflags) + $(qtgui_swig_la_swig_cxxflags) -guile/qtgui.cc: gnuradio/qtgui.scm -gnuradio/qtgui.scm: qtgui.i -gnuradio/qtgui-primitive.scm: gnuradio/qtgui.scm +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.d +-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/swig/qtgui_sink_f.i b/gr-qtgui/swig/qtgui_sink_f.i new file mode 100644 index 000000000..c5eb656b9 --- /dev/null +++ b/gr-qtgui/swig/qtgui_sink_f.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_f.h> +%} + +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 plottime=true, bool plotconst=true, + QWidget *parent=NULL); + +class qtgui_sink_f : public gr_block +{ +private: + friend 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 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 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/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); +}; |