commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 01/02: qtgui: Adds a QTGUI edit box block t


From: git
Subject: [Commit-gnuradio] [gnuradio] 01/02: qtgui: Adds a QTGUI edit box block that emits a message when changed.
Date: Tue, 26 Apr 2016 22:29:21 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

jcorgan pushed a commit to branch master
in repository gnuradio.

commit 46e49782d92fa759fe22d9092bedd6052c739a8e
Author: Tom Rondeau <address@hidden>
Date:   Tue Apr 26 14:32:19 2016 -0400

    qtgui: Adds a QTGUI edit box block that emits a message when changed.
    
    Unlike the current QT GUI Entry Widget, this is an actual GNU Radio
    block with an output message port 'msg'. When the editing is finished
    (enter or change in scope), it triggers the editing_finished method
    that publishes the text in the box as a message.
    
    Also allows setting of the value through an input message port.
    
    Adds example test_qtgui_msg.grc to explore this.
---
 gr-qtgui/doc/qtgui.dox                         |  48 ++
 gr-qtgui/examples/CMakeLists.txt               |   1 +
 gr-qtgui/examples/test_qtgui_msg.grc           | 978 +++++++++++++++++++++++++
 gr-qtgui/grc/qtgui_block_tree.xml              |   1 +
 gr-qtgui/grc/qtgui_edit_box_msg.xml            | 152 ++++
 gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt |   1 +
 gr-qtgui/include/gnuradio/qtgui/edit_box_msg.h | 151 ++++
 gr-qtgui/include/gnuradio/qtgui/qtgui_types.h  |  20 +-
 gr-qtgui/lib/CMakeLists.txt                    |   2 +
 gr-qtgui/lib/edit_box_msg_impl.cc              | 571 +++++++++++++++
 gr-qtgui/lib/edit_box_msg_impl.h               |  93 +++
 gr-qtgui/swig/qtgui_swig.i                     |  15 +
 12 files changed, 2032 insertions(+), 1 deletion(-)

diff --git a/gr-qtgui/doc/qtgui.dox b/gr-qtgui/doc/qtgui.dox
index d95ab19..d0d7345 100644
--- a/gr-qtgui/doc/qtgui.dox
+++ b/gr-qtgui/doc/qtgui.dox
@@ -232,6 +232,54 @@ tb.msg_connect((msg_block, 'msg'), (tsnk, 'in'))
 \endcode
 
 
+\section qtgui_widgets QTGUI Widgets
+
+The QTGUI component also includes a number of widgets that can be used
+to perform live updates of variables through standard QT input
+widgets. Most of the widgets are implemented directly in Python
+through PyQT. However, GNU Radio is introducing more widgets, written
+and therefore available in C++ that also produce messsages. The
+Python-based widgets only act as variables and so as they are changed,
+any block using those widgets to set paramters has the callback (i.e.,
+set_value()) function's called.
+
+\subsection qtgui_widgets_python Python widgets:
+
+\li Range: creates a slider and/or combo box to change to set/change
+the value of a parameter. This widget can set either float of int
+values.
+\li Entry: An edit box that allows a user to directly set a
+new value for the parameter.
+\li Chooser: Creates a drop-down menu of pre-set values.
+\li Check Box: Creates a check box. The user sets what the value of
+the check means when enabled or disabled.
+\li Push Button: Adds a button that changes state when pushed versus
+released (no sticky). The user sets up what the value is when pressed
+versus when released.
+\li Label: Adds a Label widget to annotate the GUI. Generally not used
+as a variable.
+\li Tab Widget: Adds a tab widget that can house other GUI widgets to
+format the interface. Use the GUI hint of the other QT widgets and
+instruments to specify if and where they exist in the tab widget using
+the format "tag widget address@hidden: row, col, row span, col
+span". Simply using "tab widget address@hidden" will put that widget into
+the specific index (starting at 0) of the tab widget while adding the
+"row, col, row span, col span" will allow the user to place them in
+the tab grid.
+\li
+
+
+\subsection qtgui_widgets_cpp C++ and Message-Passing Widgets
+
+\li \ref gr::qtgui::edit_box_msg "Message Edit Box": A QT edit box
+that emits a message when editing is done (e.g., user presses enter,
+tabs out of the widget, or mouse-clicks out of the widget). The
+message type is settable as are the contents. Messages can be sent as
+key:value pairs when Pair Mode is enabled. When Static Mode is
+enabled, the data type and the pair key (if in Pair Mode) are set at
+the start and cannot be changed at runtime.
+
+
 \section qtgui_configuration Configuration
 
 There is currently a single configuration option in the preferences
diff --git a/gr-qtgui/examples/CMakeLists.txt b/gr-qtgui/examples/CMakeLists.txt
index 3581bda..5662dfa 100644
--- a/gr-qtgui/examples/CMakeLists.txt
+++ b/gr-qtgui/examples/CMakeLists.txt
@@ -41,6 +41,7 @@ install(
     qtgui_tags_viewing.grc
     qtgui_vector_sink_example.grc
     qtgui_message_inputs.grc
+    test_qtgui_msg.grc
     DESTINATION ${GR_PKG_QTGUI_EXAMPLES_DIR}
     COMPONENT "qtgui_python"
 )
diff --git a/gr-qtgui/examples/test_qtgui_msg.grc 
b/gr-qtgui/examples/test_qtgui_msg.grc
new file mode 100644
index 0000000..12ca0e3
--- /dev/null
+++ b/gr-qtgui/examples/test_qtgui_msg.grc
@@ -0,0 +1,978 @@
+<?xml version='1.0' encoding='utf-8'?>
+<?grc format='1' created='3.7.10'?>
+<flow_graph>
+  <timestamp>Wed Feb 10 14:28:57 2016</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>comment</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(8, 11)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>qt_gui</value>
+    </param>
+    <param>
+      <key>hier_block_src_path</key>
+      <value>.:</value>
+    </param>
+    <param>
+      <key>id</key>
+      <value>test_qtgui_msg</value>
+    </param>
+    <param>
+      <key>max_nouts</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>qt_qss_theme</key>
+      <value></value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>run_command</key>
+      <value>{python} -u {filename}</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>prompt</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>thread_safe_setters</key>
+      <value></value>
+    </param>
+    <param>
+      <key>title</key>
+      <value></value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>comment</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(168, 11)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32000</value>
+    </param>
+  </block>
+  <block>
+    <key>analog_sig_source_x</key>
+    <param>
+      <key>amp</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>comment</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>freq</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(80, 83)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>id</key>
+      <value>analog_sig_source_x_0</value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>offset</key>
+      <value>0</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>analog.GR_COS_WAVE</value>
+    </param>
+  </block>
+  <block>
+    <key>blocks_message_debug</key>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>comment</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(600, 481)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>id</key>
+      <value>blocks_message_debug_0</value>
+    </param>
+  </block>
+  <block>
+    <key>qtgui_edit_box_msg</key>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>comment</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(104, 219)</value>
+    </param>
+    <param>
+      <key>gui_hint</key>
+      <value>0,0,1,1</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>id</key>
+      <value>qtgui_edit_box_msg_0</value>
+    </param>
+    <param>
+      <key>key</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value>Frequency</value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>is_pair</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>is_static</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value></value>
+    </param>
+  </block>
+  <block>
+    <key>qtgui_edit_box_msg</key>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>comment</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(88, 371)</value>
+    </param>
+    <param>
+      <key>gui_hint</key>
+      <value>3,1,1,1</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>id</key>
+      <value>qtgui_edit_box_msg_0_0</value>
+    </param>
+    <param>
+      <key>key</key>
+      <value></value>
+    </param>
+    <param>
+      <key>label</key>
+      <value></value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>is_pair</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>is_static</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>int_vec</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value></value>
+    </param>
+  </block>
+  <block>
+    <key>qtgui_edit_box_msg</key>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>comment</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(272, 499)</value>
+    </param>
+    <param>
+      <key>gui_hint</key>
+      <value>3,0,1,1</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>id</key>
+      <value>qtgui_edit_box_msg_0_0_0</value>
+    </param>
+    <param>
+      <key>key</key>
+      <value></value>
+    </param>
+    <param>
+      <key>label</key>
+      <value></value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>is_pair</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>is_static</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>int_vec</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value></value>
+    </param>
+  </block>
+  <block>
+    <key>qtgui_freq_sink_x</key>
+    <param>
+      <key>autoscale</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>bw</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>fc</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>comment</key>
+      <value></value>
+    </param>
+    <param>
+      <key>ctrlpanel</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>fftsize</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(512, 195)</value>
+    </param>
+    <param>
+      <key>gui_hint</key>
+      <value>1,0,1,2</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>grid</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>id</key>
+      <value>qtgui_freq_sink_x_0</value>
+    </param>
+    <param>
+      <key>legend</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>alpha1</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color1</key>
+      <value>"blue"</value>
+    </param>
+    <param>
+      <key>label1</key>
+      <value></value>
+    </param>
+    <param>
+      <key>width1</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>alpha10</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color10</key>
+      <value>"dark blue"</value>
+    </param>
+    <param>
+      <key>label10</key>
+      <value></value>
+    </param>
+    <param>
+      <key>width10</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>alpha2</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color2</key>
+      <value>"red"</value>
+    </param>
+    <param>
+      <key>label2</key>
+      <value></value>
+    </param>
+    <param>
+      <key>width2</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>alpha3</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color3</key>
+      <value>"green"</value>
+    </param>
+    <param>
+      <key>label3</key>
+      <value></value>
+    </param>
+    <param>
+      <key>width3</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>alpha4</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color4</key>
+      <value>"black"</value>
+    </param>
+    <param>
+      <key>label4</key>
+      <value></value>
+    </param>
+    <param>
+      <key>width4</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>alpha5</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color5</key>
+      <value>"cyan"</value>
+    </param>
+    <param>
+      <key>label5</key>
+      <value></value>
+    </param>
+    <param>
+      <key>width5</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>alpha6</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color6</key>
+      <value>"magenta"</value>
+    </param>
+    <param>
+      <key>label6</key>
+      <value></value>
+    </param>
+    <param>
+      <key>width6</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>alpha7</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color7</key>
+      <value>"yellow"</value>
+    </param>
+    <param>
+      <key>label7</key>
+      <value></value>
+    </param>
+    <param>
+      <key>width7</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>alpha8</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color8</key>
+      <value>"dark red"</value>
+    </param>
+    <param>
+      <key>label8</key>
+      <value></value>
+    </param>
+    <param>
+      <key>width8</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>alpha9</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color9</key>
+      <value>"dark green"</value>
+    </param>
+    <param>
+      <key>label9</key>
+      <value></value>
+    </param>
+    <param>
+      <key>width9</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>name</key>
+      <value>""</value>
+    </param>
+    <param>
+      <key>nconnections</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>showports</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>freqhalf</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>tr_chan</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>tr_level</key>
+      <value>0.0</value>
+    </param>
+    <param>
+      <key>tr_mode</key>
+      <value>qtgui.TRIG_MODE_FREE</value>
+    </param>
+    <param>
+      <key>tr_tag</key>
+      <value>""</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>update_time</key>
+      <value>0.10</value>
+    </param>
+    <param>
+      <key>wintype</key>
+      <value>firdes.WIN_BLACKMAN_hARRIS</value>
+    </param>
+    <param>
+      <key>ymax</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ymin</key>
+      <value>-140</value>
+    </param>
+  </block>
+  <block>
+    <key>qtgui_waterfall_sink_x</key>
+    <param>
+      <key>bw</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>fc</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>comment</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>fftsize</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(512, 115)</value>
+    </param>
+    <param>
+      <key>gui_hint</key>
+      <value>2,0,1,2</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>grid</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>id</key>
+      <value>qtgui_waterfall_sink_x_0</value>
+    </param>
+    <param>
+      <key>int_max</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>int_min</key>
+      <value>-140</value>
+    </param>
+    <param>
+      <key>legend</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>alpha1</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color1</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>label1</key>
+      <value></value>
+    </param>
+    <param>
+      <key>alpha10</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color10</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>label10</key>
+      <value></value>
+    </param>
+    <param>
+      <key>alpha2</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color2</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>label2</key>
+      <value></value>
+    </param>
+    <param>
+      <key>alpha3</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color3</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>label3</key>
+      <value></value>
+    </param>
+    <param>
+      <key>alpha4</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color4</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>label4</key>
+      <value></value>
+    </param>
+    <param>
+      <key>alpha5</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color5</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>label5</key>
+      <value></value>
+    </param>
+    <param>
+      <key>alpha6</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color6</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>label6</key>
+      <value></value>
+    </param>
+    <param>
+      <key>alpha7</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color7</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>label7</key>
+      <value></value>
+    </param>
+    <param>
+      <key>alpha8</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color8</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>label8</key>
+      <value></value>
+    </param>
+    <param>
+      <key>alpha9</key>
+      <value>1.0</value>
+    </param>
+    <param>
+      <key>color9</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>label9</key>
+      <value></value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>name</key>
+      <value>""</value>
+    </param>
+    <param>
+      <key>nconnections</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>showports</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>freqhalf</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>update_time</key>
+      <value>0.10</value>
+    </param>
+    <param>
+      <key>wintype</key>
+      <value>firdes.WIN_BLACKMAN_hARRIS</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>analog_sig_source_x_0</source_block_id>
+    <sink_block_id>qtgui_freq_sink_x_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>analog_sig_source_x_0</source_block_id>
+    <sink_block_id>qtgui_waterfall_sink_x_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>qtgui_edit_box_msg_0</source_block_id>
+    <sink_block_id>qtgui_freq_sink_x_0</sink_block_id>
+    <source_key>msg</source_key>
+    <sink_key>freq</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>qtgui_edit_box_msg_0</source_block_id>
+    <sink_block_id>qtgui_waterfall_sink_x_0</sink_block_id>
+    <source_key>msg</source_key>
+    <sink_key>freq</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>qtgui_edit_box_msg_0_0</source_block_id>
+    <sink_block_id>qtgui_edit_box_msg_0_0_0</sink_block_id>
+    <source_key>msg</source_key>
+    <sink_key>val</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>qtgui_edit_box_msg_0_0_0</source_block_id>
+    <sink_block_id>blocks_message_debug_0</sink_block_id>
+    <source_key>msg</source_key>
+    <sink_key>print</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>qtgui_edit_box_msg_0_0_0</source_block_id>
+    <sink_block_id>qtgui_edit_box_msg_0_0</sink_block_id>
+    <source_key>msg</source_key>
+    <sink_key>val</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>qtgui_freq_sink_x_0</source_block_id>
+    <sink_block_id>qtgui_edit_box_msg_0</sink_block_id>
+    <source_key>freq</source_key>
+    <sink_key>val</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>qtgui_freq_sink_x_0</source_block_id>
+    <sink_block_id>qtgui_freq_sink_x_0</sink_block_id>
+    <source_key>freq</source_key>
+    <sink_key>freq</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>qtgui_waterfall_sink_x_0</source_block_id>
+    <sink_block_id>qtgui_edit_box_msg_0</sink_block_id>
+    <source_key>freq</source_key>
+    <sink_key>val</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>qtgui_waterfall_sink_x_0</source_block_id>
+    <sink_block_id>qtgui_waterfall_sink_x_0</sink_block_id>
+    <source_key>freq</source_key>
+    <sink_key>freq</sink_key>
+  </connection>
+</flow_graph>
diff --git a/gr-qtgui/grc/qtgui_block_tree.xml 
b/gr-qtgui/grc/qtgui_block_tree.xml
index 03db638..300c7a7 100644
--- a/gr-qtgui/grc/qtgui_block_tree.xml
+++ b/gr-qtgui/grc/qtgui_block_tree.xml
@@ -55,6 +55,7 @@
       <block>variable_qtgui_push_button</block>
       <block>variable_qtgui_entry</block>
       <block>variable_qtgui_label</block>
+      <block>qtgui_edit_box_msg</block>
     </cat>
   </cat>
 </cat>
diff --git a/gr-qtgui/grc/qtgui_edit_box_msg.xml 
b/gr-qtgui/grc/qtgui_edit_box_msg.xml
new file mode 100644
index 0000000..c7c758a
--- /dev/null
+++ b/gr-qtgui/grc/qtgui_edit_box_msg.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##QT GUI Edit Box that sends messages
+###################################################
+ -->
+<block>
+  <name>QT GUI Message Edit Box</name>
+  <key>qtgui_edit_box_msg</key>
+  <import>from PyQt4 import Qt</import>
+  <import>from gnuradio import qtgui</import>
+  <import>import sip</import>
+  <make>#set $win = 'self._%s_win'%$id
+qtgui.edit_box_msg($(type.t), $value, $label, $is_pair, $is_static, $key)
+self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget)
+$(gui_hint()($win))</make>
+
+  <param>
+    <name>Type</name>
+    <key>type</key>
+    <value>string</value>
+    <type>enum</type>
+    <option>
+      <name>String</name>
+      <key>string</key>
+      <opt>t:qtgui.STRING</opt>
+    </option>
+    <option>
+      <name>Int</name>
+      <key>int</key>
+      <opt>t:qtgui.INT</opt>
+    </option>
+    <option>
+      <name>Float</name>
+      <key>float</key>
+      <opt>t:qtgui.FLOAT</opt>
+    </option>
+    <option>
+      <name>Double</name>
+      <key>double</key>
+      <opt>t:qtgui.DOUBLE</opt>
+    </option>
+    <option>
+      <name>Complex</name>
+      <key>complex</key>
+      <opt>t:qtgui.COMPLEX</opt>
+    </option>
+    <option>
+      <name>Int (Vec)</name>
+      <key>int_vec</key>
+      <opt>t:qtgui.INT_VEC</opt>
+    </option>
+    <option>
+      <name>Float (Vec)</name>
+      <key>flt_vec</key>
+      <opt>t:qtgui.FLOAT_VEC</opt>
+    </option>
+    <option>
+      <name>Double (Vec)</name>
+      <key>dbl_vec</key>
+      <opt>t:qtgui.DOUBLE_VEC</opt>
+    </option>
+    <option>
+      <name>Complex (Vec)</name>
+      <key>cpx_vec</key>
+      <opt>t:qtgui.COMPLEX_VEC</opt>
+    </option>
+  </param>
+
+  <param>
+    <name>Value</name>
+    <key>value</key>
+    <value></value>
+    <type>string</type>
+  </param>
+
+  <param>
+    <name>Label</name>
+    <key>label</key>
+    <value></value>
+    <type>string</type>
+  </param>
+
+  <param>
+    <name>Pair Mode</name>
+    <key>is_pair</key>
+    <value>True</value>
+    <type>enum</type>
+    <option>
+      <name>False</name>
+      <key>False</key>
+    </option>
+    <option>
+      <name>True</name>
+      <key>True</key>
+    </option>
+  </param>
+
+  <param>
+    <name>Static Mode</name>
+    <key>is_static</key>
+    <value>True</value>
+    <type>enum</type>
+    <option>
+      <name>False</name>
+      <key>False</key>
+    </option>
+    <option>
+      <name>True</name>
+      <key>True</key>
+    </option>
+  </param>
+
+  <param>
+    <name>Key</name>
+    <key>key</key>
+    <value></value>
+    <type>string</type>
+    <hide>#if $is_pair() == 'True' then 'none' else 'all'#</hide>
+  </param>
+
+  <param>
+    <name>GUI Hint</name>
+    <key>gui_hint</key>
+    <value></value>
+    <type>gui_hint</type>
+    <hide>part</hide>
+  </param>
+
+  <!-- If both is_pair and is_static are True, we require a default key.
+       If either or both are false, we don't care about a default key.
+  -->
+  <check>($is_pair and $is_static and len($key) &gt; 0) or not ($is_pair and 
$is_static)</check>
+
+  <sink>
+    <name>val</name>
+    <type>message</type>
+    <optional>1</optional>
+  </sink>
+
+  <source>
+    <name>msg</name>
+    <type>message</type>
+    <optional>1</optional>
+  </source>
+
+  <doc>
+The GUI hint can be used to position the widget within the application. \
+The hint is of the form address@hidden: [row, col, row_span, col_span]. \
+Both the tab specification and the grid position are optional.
+  </doc>
+</block>
diff --git a/gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt 
b/gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt
index 1e0c9f3..5d22f11 100644
--- a/gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt
+++ b/gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt
@@ -38,6 +38,7 @@ install(FILES
   histogram_sink_f.h
   histogramdisplayform.h
   HistogramDisplayPlot.h
+  edit_box_msg.h
   number_sink.h
   numberdisplayform.h
   plot_raster.h
diff --git a/gr-qtgui/include/gnuradio/qtgui/edit_box_msg.h 
b/gr-qtgui/include/gnuradio/qtgui/edit_box_msg.h
new file mode 100644
index 0000000..2976cfb
--- /dev/null
+++ b/gr-qtgui/include/gnuradio/qtgui/edit_box_msg.h
@@ -0,0 +1,151 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2016 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_EDIT_BOX_MSG_H
+#define INCLUDED_QTGUI_EDIT_BOX_MSG_H
+
+#ifdef ENABLE_PYTHON
+#include <Python.h>
+#endif
+
+#include <gnuradio/qtgui/qtgui_types.h>
+#include <gnuradio/qtgui/api.h>
+#include <gnuradio/block.h>
+#include <qapplication.h>
+
+namespace gr {
+  namespace qtgui {
+
+    /*!
+     * \brief Create a QT Edit Box widget where the value is posted as a 
message.
+     * \ingroup qtgui_blk
+     *
+     * \details
+     * This block creates a QT Edit Box widget that manages data
+     * through message passing interfaces. The 'msg' output port
+     * produces messages based on the text in the edit box and the
+     * data type set by the \p type argument (see
+     * gr::qtgui::data_type_t). The data types are checked, and WARN
+     * log messages are produced when the data is in the wrong
+     * format. Not all errors are explicitly checked for, only that
+     * conversions happen correctly. Failures are either produces as
+     * log messages or the action is simply silently dropped.
+     *
+     * The value of the edit boxes can be programmatically updated
+     * through the 'val' input message port. It is also checked for
+     * the correct data type.
+     *
+     * The \p is_pair argument to the constructor determines if the
+     * edit box handles a key:value pair. If set to True, two edit
+     * boxes are created with the left for the key and right for the
+     * value. The key is always assumed to be a string and the value
+     * is restricted by the data type setting as above.
+     *
+     * The block can take a default value. Because the block is
+     * capable of handling multiple different data types, we enter the
+     * default value as a string in the same way we expect the user to
+     * enter it into the Value edit box of the widget. We convert this
+     * default exactly the same way we convert the user-entered text
+     * in the edit box. See the next paragraph for an explanation for
+     * how to handle complex numbers.
+     *
+     * Complex numbers are currently handled a bit differently than
+     * expected. Because we use the Boost lexical_cast function,
+     * complex numbers MUST be in the form "(a,b)" to represent "a +
+     * jb". Note that you cannot even have a space after the comma, so
+     * "(1.23,10.56)" is correct while "(1.23, 10.56)" will not parse.
+     *
+     * The 'static' mode prevents the user from changing the data type
+     * or the key used in the widget. If also in 'pair' mode, the key
+     * is not displayed and so must be set in the constructor. It is
+     * an error if using static and pair modes with no default key
+     * set.
+     *
+     * Message Ports:
+     *
+     * - msg (output):
+     *       Produces a PMT message from the data in the edit box. It
+     *       is packaged in the PMT container determined by the \p
+     *       type argument to the ctor. If the data in the box is not of
+     *       the correct type and the conversion fails, the block
+     *       produces a log WARN message but does nothing else with
+     *       the data. If the \p is_pair flag is set on this block, it
+     *       will produce a PMT pair object where the key (car) is
+     *       assumed to be a string and the value (cdr) is determined
+     *       by \p type.
+     *
+     * - val (input):
+     *       Accepts messages to update the value in the edit
+     *       boxes. The messages, as PMTs, are first checked to make
+     *       sure that they are the correct type (integer, float,
+     *       string, or complex), and unpacks them and converts them
+     *       to QStrings to display in the edit box. When using \p
+     *       is_pair, the PMT is checked to make sure it is a PMT
+     *       pair. Then the key (car) is extracted as a string before
+     *       the value (cdr) is processed based on the set data type
+     *       of the box.
+     */
+    class QTGUI_API edit_box_msg : virtual public block
+    {
+    public:
+      // gr::qtgui::edit_box_msg::sptr
+      typedef boost::shared_ptr<edit_box_msg> sptr;
+
+      /*!
+       * \brief Constructs the Edit box block.
+       *
+       * \param type the data type of data in the value box.
+       * \param value the default value of the message. This is
+       *        entered as a string regardless of the type and
+       *        converted internally -- much like how the block
+       *        extracts the value from the edit box and converts it.
+       * \param label a label to identify the box on screen.
+       * \param is_pair if we are using a key:value pair.
+       * \param is_static sets the key edit box as a static text box
+       *                  (cannot be edited live).
+       * \param key Set the key used in a key:value pair message.
+       * \param parent a QWidget parent in the QT app.
+       */
+      static sptr make(gr::qtgui::data_type_t type,
+                       const std::string &value="",
+                       const std::string &label="",
+                       bool is_pair=true,
+                       bool is_static=true,
+                       const std::string &key="",
+                       QWidget *parent=NULL);
+
+      virtual void exec_() = 0;
+      virtual QWidget* qwidget() = 0;
+
+#ifdef ENABLE_PYTHON
+      virtual PyObject* pyqwidget() = 0;
+#else
+      virtual void* pyqwidget() = 0;
+#endif
+
+      QApplication *d_qApplication;
+    };
+
+  } /* namespace qtgui */
+} /* namespace gr */
+
+#endif /* INCLUDED_QTGUI_EDIT_BOX_MSG_H */
diff --git a/gr-qtgui/include/gnuradio/qtgui/qtgui_types.h 
b/gr-qtgui/include/gnuradio/qtgui/qtgui_types.h
index e55746c..ae7d081 100644
--- a/gr-qtgui/include/gnuradio/qtgui/qtgui_types.h
+++ b/gr-qtgui/include/gnuradio/qtgui/qtgui_types.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2012 Free Software Foundation, Inc.
+ * Copyright 2012,2016 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -27,6 +27,24 @@
 #include <qwt_scale_draw.h>
 #include <gnuradio/high_res_timer.h>
 
+namespace gr {
+  namespace qtgui {
+
+    enum data_type_t {
+      INT = 0,
+      FLOAT,
+      DOUBLE,
+      COMPLEX,
+      STRING,
+      INT_VEC,
+      FLOAT_VEC,
+      DOUBLE_VEC,
+      COMPLEX_VEC,
+    };
+
+  } /* namespace qtgui */
+} /* namespace gr */
+
 class FreqOffsetAndPrecisionClass
 {
 public:
diff --git a/gr-qtgui/lib/CMakeLists.txt b/gr-qtgui/lib/CMakeLists.txt
index a0af95b..276c3e4 100644
--- a/gr-qtgui/lib/CMakeLists.txt
+++ b/gr-qtgui/lib/CMakeLists.txt
@@ -43,6 +43,7 @@ set(qtgui_moc_hdrs
     ${qtgui_mod_includedir}/ConstellationDisplayPlot.h
     ${qtgui_mod_includedir}/HistogramDisplayPlot.h
     ${qtgui_mod_includedir}/VectorDisplayPlot.h
+    edit_box_msg_impl.h
 )
 QT4_WRAP_CPP(qtgui_moc_sources ${qtgui_moc_hdrs})
 QT4_WRAP_UI(qtgui_ui_hdrs spectrumdisplayform.ui)
@@ -99,6 +100,7 @@ set(qtgui_sources
     ber_sink_b_impl.cc
     vectordisplayform.cc
     vector_sink_f_impl.cc
+    edit_box_msg_impl.cc
 )
 
 #Add Windows DLL resource file if using MSVC
diff --git a/gr-qtgui/lib/edit_box_msg_impl.cc 
b/gr-qtgui/lib/edit_box_msg_impl.cc
new file mode 100644
index 0000000..e0c5f64
--- /dev/null
+++ b/gr-qtgui/lib/edit_box_msg_impl.cc
@@ -0,0 +1,571 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2016 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 "edit_box_msg_impl.h"
+#include <gnuradio/io_signature.h>
+#include <gnuradio/prefs.h>
+#include <gnuradio/qtgui/utils.h>
+#include <boost/lexical_cast.hpp>
+
+namespace gr {
+  namespace qtgui {
+
+    edit_box_msg::sptr
+    edit_box_msg::make(data_type_t type, const std::string &label,
+                       const std::string &value,
+                       bool is_pair, bool is_static,
+                       const std::string &key, QWidget* parent)
+    {
+      return gnuradio::get_initial_sptr
+        (new edit_box_msg_impl(type, value, label, is_pair,
+                               is_static, key, parent));
+    }
+
+    edit_box_msg_impl::edit_box_msg_impl(data_type_t type, const std::string 
&label,
+                                         const std::string &value,
+                                         bool is_pair, bool is_static,
+                                         const std::string &key, QWidget* 
parent)
+      : block("edit_box_msg",
+              io_signature::make(0, 0, 0),
+              io_signature::make(0, 0, 0)),
+        QObject(parent)
+    {
+      // Required now for Qt; argc must be greater than 0 and argv
+      // must have at least one valid character. Must be valid through
+      // life of the qApplication:
+      // http://harmattan-dev.nokia.com/docs/library/html/qt4/qapplication.html
+      d_argc = 1;
+      d_argv = new char;
+      d_argv[0] = '\0';
+
+      if(qApp != NULL) {
+       d_qApplication = qApp;
+      }
+      else {
+#if QT_VERSION >= 0x040500
+        std::string style = prefs::singleton()->get_string("qtgui", "style", 
"raster");
+        QApplication::setGraphicsSystem(QString(style.c_str()));
+#endif
+       d_qApplication = new QApplication(d_argc, &d_argv);
+      }
+
+      // If a style sheet is set in the prefs file, enable it here.
+      std::string qssfile = prefs::singleton()->get_string("qtgui","qss","");
+      if(qssfile.size() > 0) {
+        QString sstext = get_qt_style_sheet(QString(qssfile.c_str()));
+        d_qApplication->setStyleSheet(sstext);
+      }
+
+      d_is_pair = is_pair;
+      d_is_static = is_static;
+
+      d_val = new QLineEdit();
+      d_val->setObjectName("qtgui_editboxmsg_val"); // used to set background 
color
+      d_val->setText(QString(value.c_str()));
+
+      set_type(type);
+
+      d_group = new QGroupBox();
+      d_vlayout = new QVBoxLayout(parent);
+      d_hlayout = new QHBoxLayout(parent);
+
+      if(d_is_pair) {
+        d_key = new QLineEdit();
+
+        QString key_text = QString(key.c_str());
+        d_key->setText(key_text);
+
+        // If static, we create the d_key object, which we use later
+        // to be consistent about getting the key string. But we do
+        // not add it to the layout.
+        if(d_is_static) {
+          d_key->setEnabled(false);
+
+          QFontMetrics fm = d_key->fontMetrics();
+          int width = 15 + fm.width(key_text);
+
+          d_key->setFixedWidth(width);
+
+          // Verify that a default key has been set or emit an error
+          if(key.size() == 0) {
+            throw std::runtime_error("When using static + pair mode, please 
set a default key.");
+          }
+        }
+        else {
+          // Adding it to the layout if in non-static mode so users
+          // can see and update the key.
+          d_hlayout->addWidget(d_key);
+        }
+      }
+
+      d_label = NULL;
+      if(label != "") {
+        d_label = new QLabel(QString(label.c_str()));
+        d_vlayout->addWidget(d_label);
+      }
+
+      d_hlayout->addWidget(d_val);
+
+      if(!d_is_static) {
+        // If not static, we can change the key and the data type of
+        // the value box.
+        d_type_box = new QComboBox();
+        d_type_box->setEditable(false);
+
+        // Items listed in order of enum data_type_t
+        d_type_box->addItem("Int");
+        d_type_box->addItem("Float");
+        d_type_box->addItem("Double");
+        d_type_box->addItem("Complex");
+        d_type_box->addItem("String");
+        d_type_box->addItem("Int (vec)");
+        d_type_box->addItem("Float (vec)");
+        d_type_box->addItem("Double (vec)");
+        d_type_box->addItem("Complex (vec)");
+        d_type_box->setCurrentIndex(d_type);
+        d_hlayout->addWidget(d_type_box);
+
+        QObject::connect(d_type_box, SIGNAL(currentIndexChanged(int)),
+                         this, SLOT(set_type(int)));
+      }
+
+      d_vlayout->addItem(d_hlayout);
+      d_group->setLayout(d_vlayout);
+
+      QObject::connect(d_val, SIGNAL(editingFinished()),
+                       this, SLOT(edit_finished()));
+
+      d_msg = pmt::PMT_NIL;
+
+      message_port_register_out(pmt::mp("msg"));
+      message_port_register_in(pmt::mp("val"));
+
+      set_msg_handler(pmt::mp("val"),
+                      boost::bind(&edit_box_msg_impl::set_value, this, _1));
+    }
+
+    edit_box_msg_impl::~edit_box_msg_impl()
+    {
+      delete d_argv;
+      delete d_group;
+      delete d_hlayout;
+      delete d_vlayout;
+      delete d_val;
+      if(d_is_pair)
+        delete d_key;
+      if(d_label)
+        delete d_label;
+    }
+
+    bool
+    edit_box_msg_impl::start()
+    {
+      QString text = d_val->text();
+      if(!text.isEmpty()) {
+        edit_finished();
+      }
+
+      return block::start();
+    }
+
+    void
+    edit_box_msg_impl::exec_()
+    {
+      d_qApplication->exec();
+    }
+
+    QWidget*
+    edit_box_msg_impl::qwidget()
+    {
+      return (QWidget*)d_group;
+    }
+
+#ifdef ENABLE_PYTHON
+    PyObject*
+    edit_box_msg_impl::pyqwidget()
+    {
+      PyObject *w = PyLong_FromVoidPtr((void*)d_group);
+      PyObject *retarg = Py_BuildValue("N", w);
+      return retarg;
+    }
+#else
+    void *
+    edit_box_msg_impl::pyqwidget()
+    {
+      return NULL;
+    }
+#endif
+
+    void
+    edit_box_msg_impl::set_type(int type)
+    {
+      set_type(static_cast<data_type_t>(type));
+    }
+
+    void
+    edit_box_msg_impl::set_type(gr::qtgui::data_type_t type)
+    {
+      d_type = type;
+
+      switch(d_type) {
+      case INT:
+      case INT_VEC:
+        d_val->setStyleSheet("QLineEdit#qtgui_editboxmsg_val 
{background-color: #4CAF50;}");
+        break;
+      case FLOAT:
+      case FLOAT_VEC:
+        d_val->setStyleSheet("QLineEdit#qtgui_editboxmsg_val 
{background-color: #F57C00;}");
+        break;
+      case DOUBLE:
+      case DOUBLE_VEC:
+        d_val->setStyleSheet("QLineEdit#qtgui_editboxmsg_val 
{background-color: #00BCD4;}");
+        break;
+      case COMPLEX:
+      case COMPLEX_VEC:
+        d_val->setStyleSheet("QLineEdit#qtgui_editboxmsg_val 
{background-color: #2196F3;}");
+        break;
+      case STRING:
+        d_val->setStyleSheet("QLineEdit#qtgui_editboxmsg_val 
{background-color: #FFFFFF; color: #000000;}");
+        break;
+      }
+    }
+
+    void
+    edit_box_msg_impl::set_value(pmt::pmt_t val)
+    {
+      // If the contents of the new value are the same as we already
+      // had, don't update anything, just exit and move on.
+      if(pmt::eqv(val, d_msg)) {
+        return;
+      }
+
+      int xi;
+      float xf;
+      double xd;
+      std::string xs;
+      gr_complex xc;
+
+      d_msg = val;
+
+      // Only update key if we're expecting a pair
+      if(d_is_pair) {
+        // If we are, make sure that the PMT is actually a pair
+        if(pmt::is_pair(val)) {
+          pmt::pmt_t key = pmt::car(val);
+          std::string skey = pmt::symbol_to_string(key);
+
+          // If static, check to make sure that the key of the
+          // incoming message matches our key. If it doesn't, emit a
+          // warning and exit without changing anything.
+          if(d_is_static) {
+            std::string cur_key = d_key->text().toStdString();
+            if(skey != cur_key) {
+              GR_LOG_WARN(d_logger, boost::format("Got key '%1%' but expected 
'%2%'") \
+                          % skey % cur_key);
+              return;
+            }
+          }
+          val = pmt::cdr(val);
+          d_key->setText(QString(skey.c_str()));
+        }
+        else {
+          GR_LOG_WARN(d_logger, "Did not find PMT pair");
+          return;
+        }
+      }
+
+      switch(d_type) {
+      case INT:
+        if(pmt::is_integer(val)) {
+          xi = pmt::to_long(val);
+          d_val->setText(QString::number(xi));
+        }
+        else {
+          GR_LOG_WARN(d_logger, "Conversion from integer failed");
+          return;
+        }
+        break;
+      case INT_VEC:
+        if(pmt::is_s32vector(val)) {
+          QStringList text_list;
+          const std::vector<int32_t> xv = pmt::s32vector_elements(val);
+          for(size_t i = 0; i < xv.size(); i++) {
+            text_list.append(QString::number(xv[i]));
+          }
+          d_val->setText(text_list.join(", "));
+        }
+        else {
+          GR_LOG_WARN(d_logger, "Conversion from integer vector failed");
+          return;
+        }
+        break;
+      case FLOAT:
+        if(pmt::is_real(val)) {
+          xf = pmt::to_float(val);
+          d_val->setText(QString::number(xf));
+        }
+        else {
+          GR_LOG_WARN(d_logger, "Conversion from float failed");
+          return;
+        }
+        break;
+      case FLOAT_VEC:
+        if(pmt::is_f32vector(val)) {
+          QStringList text_list;
+          const std::vector<float> xv = pmt::f32vector_elements(val);
+          for(size_t i = 0; i < xv.size(); i++) {
+            text_list.append(QString::number(xv[i]));
+          }
+          d_val->setText(text_list.join(", "));
+        }
+        else {
+          GR_LOG_WARN(d_logger, "Conversion from float vector failed");
+          return;
+        }
+        break;
+      case DOUBLE:
+        if(pmt::is_real(val)) {
+          xd = pmt::to_double(val);
+          d_val->setText(QString::number(xd));
+        }
+        else {
+          GR_LOG_WARN(d_logger, "Conversion from double failed");
+          return;
+        }
+        break;
+      case DOUBLE_VEC:
+        if(pmt::is_f64vector(val)) {
+          QStringList text_list;
+          const std::vector<double> xv = pmt::f64vector_elements(val);
+          for(size_t i = 0; i < xv.size(); i++) {
+            text_list.append(QString::number(xv[i]));
+          }
+          d_val->setText(text_list.join(", "));
+        }
+        else {
+          GR_LOG_WARN(d_logger, "Conversion from double vector failed");
+          return;
+        }
+        break;
+      case COMPLEX:
+        if(pmt::is_complex(val)) {
+          xc = pmt::to_complex(val);
+          d_val->setText(QString("(%1,%2)").arg(xc.real()).arg(xc.imag()));
+        }
+        else {
+          GR_LOG_WARN(d_logger, "Conversion from complex failed");
+          return;
+        }
+        break;
+      case COMPLEX_VEC:
+        if(pmt::is_c32vector(val)) {
+          QStringList text_list;
+          const std::vector<gr_complex> xv = pmt::c32vector_elements(val);
+          for(size_t i = 0; i < xv.size(); i++) {
+            
text_list.append(QString("(%1,%2)").arg(xv[i].real()).arg(xv[i].imag()));
+          }
+          d_val->setText(text_list.join(", "));
+        }
+        else {
+          GR_LOG_WARN(d_logger, "Conversion from complex vector failed");
+          return;
+        }
+        break;
+      case STRING:
+        if(pmt::is_symbol(val)) {
+          xs = pmt::symbol_to_string(val);
+          d_val->setText(QString(xs.c_str()));
+        }
+        else {
+          GR_LOG_WARN(d_logger, "Conversion from string failed");
+          return;
+        }
+        break;
+      }
+
+      // Emit the new message to pass updates downstream.
+      // Loops are prevented by the early exit if d_msg == val.
+      message_port_pub(pmt::mp("msg"), d_msg);
+    }
+
+    void
+    edit_box_msg_impl::edit_finished()
+    {
+      QString text = d_val->text();
+      bool conv_ok = true;
+      int xi;
+      float xf;
+      double xd;
+      std::string xs;
+      gr_complex xc;
+
+      switch(d_type) {
+      case INT:
+        xi = text.toInt(&conv_ok);
+        if(conv_ok) {
+          d_msg = pmt::from_long(xi);
+        }
+        else {
+          GR_LOG_WARN(d_logger, "Conversion to integer failed");
+          return;
+        }
+        break;
+      case INT_VEC:
+        {
+          std::vector<int32_t> xv;
+          QStringList text_list = text.split(",");
+          for(int i = 0; i < text_list.size(); ++i) {
+            QString s = text_list.at(i);
+            s = s.remove(QChar(' '));
+            int t = s.toInt(&conv_ok);
+            if(conv_ok) {
+              xv.push_back(t);
+            }
+            else {
+              GR_LOG_WARN(d_logger, "Conversion to integer vector failed");
+              return;
+            }
+          }
+          d_msg = pmt::init_s32vector(xv.size(), xv);
+        }
+        break;
+      case FLOAT:
+        xf = text.toFloat(&conv_ok);
+        if(conv_ok) {
+          d_msg = pmt::from_float(xf);
+        }
+        else {
+          GR_LOG_WARN(d_logger, "Conversion to float failed");
+          return;
+        }
+        break;
+      case FLOAT_VEC:
+        {
+          std::vector<float> xv;
+          QStringList text_list = text.split(",");
+          for(int i = 0; i < text_list.size(); ++i) {
+            QString s = text_list.at(i);
+            s = s.remove(QChar(' '));
+            float t = s.toFloat(&conv_ok);
+            if(conv_ok) {
+              xv.push_back(t);
+            }
+            else {
+              GR_LOG_WARN(d_logger, "Conversion to float vector failed");
+              return;
+            }
+          }
+          d_msg = pmt::init_f32vector(xv.size(), xv);
+        }
+        break;
+      case DOUBLE:
+        xd = text.toDouble(&conv_ok);
+        if(conv_ok) {
+          d_msg = pmt::from_double(xd);
+        }
+        else {
+          GR_LOG_WARN(d_logger, "Conversion to double failed");
+          return;
+        }
+        break;
+      case DOUBLE_VEC:
+        {
+          std::vector<double> xv;
+          QStringList text_list = text.split(",");
+          for(int i = 0; i < text_list.size(); ++i) {
+            QString s = text_list.at(i);
+            s = s.remove(QChar(' '));
+            double t = s.toDouble(&conv_ok);
+            if(conv_ok) {
+              xv.push_back(t);
+            }
+            else {
+              GR_LOG_WARN(d_logger, "Conversion to double vector failed");
+              return;
+            }
+          }
+          d_msg = pmt::init_f64vector(xv.size(), xv);
+        }
+        break;
+      case COMPLEX:
+        try {
+          xc = boost::lexical_cast<gr_complex>(text.toStdString());
+        }
+        catch(boost::bad_lexical_cast const & e) {
+          GR_LOG_WARN(d_logger, boost::format("Conversion to complex failed 
(%1%)") \
+                      % e.what());
+          return;
+        }
+        d_msg = pmt::from_complex(xc.real(), xc.imag());
+        break;
+      case COMPLEX_VEC:
+        {
+          std::vector<gr_complex> xv;
+          QStringList text_list = text.split(",");
+          bool even = false;
+          gr_complex c;
+          float re, im;
+          for(int i = 0; i < text_list.size(); ++i) {
+            QString s = text_list.at(i);
+            s = s.remove(QChar(' '));
+            s = s.remove(QChar(')'));
+            s = s.remove(QChar('('));
+            float t = s.toFloat(&conv_ok);
+            if(conv_ok) {
+              if(even) {
+                im = t;
+                xv.push_back(gr_complex(re, im));
+                even = false;
+              }
+              else {
+                re = t;
+                even = true;
+              }
+            }
+            else {
+              GR_LOG_WARN(d_logger, "Conversion to complex vector failed");
+              return;
+            }
+          }
+          d_msg = pmt::init_c32vector(xv.size(), xv);
+        }
+        break;
+      case STRING:
+        xs = text.toStdString();
+        d_msg = pmt::intern(xs);
+        break;
+      }
+
+      if(d_is_pair) {
+        std::string key = d_key->text().toStdString();
+        d_msg = pmt::cons(pmt::intern(key), d_msg);
+      }
+
+      message_port_pub(pmt::mp("msg"), d_msg);
+    }
+
+  } /* namespace qtgui */
+} /* namespace gr */
diff --git a/gr-qtgui/lib/edit_box_msg_impl.h b/gr-qtgui/lib/edit_box_msg_impl.h
new file mode 100644
index 0000000..c60b3de
--- /dev/null
+++ b/gr-qtgui/lib/edit_box_msg_impl.h
@@ -0,0 +1,93 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2016 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_EDIT_BOX_MSG_IMPL_H
+#define INCLUDED_QTGUI_EDIT_BOX_MSG_IMPL_H
+
+#include <gnuradio/qtgui/edit_box_msg.h>
+#include <QGroupBox>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QLineEdit>
+#include <QComboBox>
+#include <QLabel>
+
+namespace gr {
+  namespace qtgui {
+
+    class QTGUI_API edit_box_msg_impl
+      : public QObject, public edit_box_msg
+    {
+      Q_OBJECT
+
+    private:
+      int d_argc;
+      char *d_argv;
+      data_type_t d_type;
+      bool d_is_pair;
+      bool d_is_static;
+
+      QGroupBox *d_group;
+      QVBoxLayout *d_vlayout;
+      QHBoxLayout *d_hlayout;
+      QLabel *d_label;
+      QLineEdit *d_val;
+      QLineEdit *d_key;
+      QComboBox *d_type_box;
+
+      pmt::pmt_t d_msg;
+
+    public:
+      edit_box_msg_impl(gr::qtgui::data_type_t type,
+                        const std::string &value="",
+                        const std::string &label="",
+                        bool is_pair=false,
+                        bool is_static=true,
+                        const std::string &key="",
+                        QWidget* parent=0);
+      ~edit_box_msg_impl();
+
+      // Overload the start method of gr::block to emit a message if a
+      // default value is provided.
+      bool start();
+
+      void exec_();
+      QWidget*  qwidget();
+
+#ifdef ENABLE_PYTHON
+      PyObject* pyqwidget();
+#else
+      void* pyqwidget();
+#endif
+
+      void set_value(pmt::pmt_t val);
+
+    public slots:
+      void edit_finished();
+      void set_type(int);
+      void set_type(gr::qtgui::data_type_t type);
+    };
+
+  } /* namespace qtgui */
+} /* namespace gr */
+
+#endif /* INCLUDED_QTGUI_EDIT_BOX_MSG_IMPL_H */
diff --git a/gr-qtgui/swig/qtgui_swig.i b/gr-qtgui/swig/qtgui_swig.i
index 9664a71..d9595e4 100644
--- a/gr-qtgui/swig/qtgui_swig.i
+++ b/gr-qtgui/swig/qtgui_swig.i
@@ -37,6 +37,18 @@ namespace gr {
       NUM_GRAPH_VERT,
     };
 
+    enum data_type_t {
+      INT = 0,
+      FLOAT,
+      DOUBLE,
+      COMPLEX,
+      STRING,
+      INT_VEC,
+      FLOAT_VEC,
+      DOUBLE_VEC,
+      COMPLEX_VEC,
+    };
+
   } /* namespace qtgui */
 } /* namespace gr */
 
@@ -75,6 +87,7 @@ enum{
 #include "gnuradio/qtgui/number_sink.h"
 #include "gnuradio/qtgui/ber_sink_b.h"
 #include "gnuradio/qtgui/vector_sink_f.h"
+#include "gnuradio/qtgui/edit_box_msg.h"
 %}
 
 %include "gnuradio/qtgui/sink_c.h"
@@ -92,6 +105,7 @@ enum{
 %include "gnuradio/qtgui/number_sink.h"
 %include "gnuradio/qtgui/ber_sink_b.h"
 %include "gnuradio/qtgui/vector_sink_f.h"
+%include "gnuradio/qtgui/edit_box_msg.h"
 
 GR_SWIG_BLOCK_MAGIC2(qtgui, sink_c);
 GR_SWIG_BLOCK_MAGIC2(qtgui, sink_f);
@@ -108,3 +122,4 @@ GR_SWIG_BLOCK_MAGIC2(qtgui, histogram_sink_f);
 GR_SWIG_BLOCK_MAGIC2(qtgui, number_sink);
 GR_SWIG_BLOCK_MAGIC2(qtgui, ber_sink_b);
 GR_SWIG_BLOCK_MAGIC2(qtgui, vector_sink_f);
+GR_SWIG_BLOCK_MAGIC2(qtgui, edit_box_msg);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]