Browse Source

ifft hier block works on gnuradio 3.8

gr-3.8
Clemens Richter 4 years ago
parent
commit
db2f8b765e
  1. 2
      CMakeLists.txt
  2. 4
      apps/fft-multi-decoder_fixed_rtlsdr.grc
  3. 4513
      apps/ifft-RDS-decoder_hier-block.grc
  4. 1005
      apps/read_sync_decim.grc
  5. 28
      grc/CMakeLists.txt
  6. 25
      grc/multirds_decoder_compare.block.yml
  7. 28
      grc/multirds_decoder_compare.xml
  8. 57
      grc/multirds_pilot_SNR.block.yml
  9. 84
      grc/multirds_pilot_SNR.xml
  10. 136
      grc/multirds_qtgui_range.xml
  11. 23
      grc/multirds_rds_decoder.block.yml
  12. 45
      grc/multirds_rds_decoder.xml
  13. 23
      grc/multirds_rds_decoder_redsea.block.yml
  14. 45
      grc/multirds_rds_decoder_redsea.xml
  15. 86
      grc/multirds_rds_parser_table_qt.block.yml
  16. 141
      grc/multirds_rds_parser_table_qt.xml
  17. 37
      grc/multirds_rds_table_qt.block.yml
  18. 46
      grc/multirds_rds_table_qt.xml
  19. 52
      grc/multirds_station_search.block.yml
  20. 78
      grc/multirds_station_search.xml
  21. 29
      grc/multirds_stream_router.block.yml
  22. 54
      grc/multirds_stream_router.xml
  23. 30
      grc/multirds_stream_selector.block.yml
  24. 38
      grc/multirds_stream_selector.xml
  25. 30
      grc/multirds_symbol_combiner.block.yml
  26. 70
      grc/multirds_symbol_combiner.xml
  27. 62
      grc/multirds_tmc_parser.block.yml
  28. 112
      grc/multirds_tmc_parser.xml
  29. 37
      grc/multirds_variable_setter.block.yml
  30. 59
      grc/multirds_variable_setter.xml
  31. 55
      grc/multirds_vector_cutter.block.yml
  32. 87
      grc/multirds_vector_cutter.xml
  33. 4
      python/CMakeLists.txt
  34. 25
      python/__init__.py
  35. 279
      python/qtgui_range.py

2
CMakeLists.txt

@ -127,7 +127,7 @@ find_package(Doxygen)
# caps such as FILTER or FFT) and change the version to the minimum
# API compatible version required.
set(GR_REQUIRED_COMPONENTS RUNTIME)
find_package(Gnuradio "3.7.2" REQUIRED)
find_package(Gnuradio "3.8" REQUIRED)
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules)
include(GrVersion)

4
apps/fft-multi-decoder_fixed_rtlsdr.grc

@ -2282,7 +2282,7 @@ class blk(gr.sync_block): # other base classes are basic_block, decim_block, in
</param>
<param>
<key>workdir</key>
<value>/media/clemens/intdaten/uni_bulk/forschungsarbeit/data/</value>
<value>/media/clemens/teratemp/tmp/gr-multirds/data/</value>
</param>
<param>
<key>writeDB</key>
@ -2341,7 +2341,7 @@ class blk(gr.sync_block): # other base classes are basic_block, decim_block, in
</param>
<param>
<key>workdir</key>
<value>/media/clemens/intdaten/uni_bulk/forschungsarbeit/data/</value>
<value>/media/clemens/teratemp/tmp/gr-multirds/data/</value>
</param>
<param>
<key>writeDB</key>

4513
apps/ifft-RDS-decoder_hier-block.grc

File diff suppressed because it is too large Load Diff

1005
apps/read_sync_decim.grc

File diff suppressed because it is too large Load Diff

28
grc/CMakeLists.txt

@ -17,18 +17,18 @@
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
install(FILES
multirds_rds_table_qt.xml
multirds_rds_parser_table_qt.xml
multirds_rds_decoder.xml
multirds_station_search.xml
multirds_stream_selector.xml
multirds_vector_cutter.xml
multirds_decoder_compare.xml
multirds_symbol_combiner.xml
multirds_rds_decoder_redsea.xml
multirds_qtgui_range.xml
multirds_variable_setter.xml
multirds_tmc_parser.xml
multirds_pilot_SNR.xml
multirds_stream_router.xml DESTINATION share/gnuradio/grc/blocks
multirds_rds_table_qt.block.yml
multirds_rds_parser_table_qt.block.yml
multirds_rds_decoder.block.yml
multirds_station_search.block.yml
multirds_stream_selector.block.yml
multirds_vector_cutter.block.yml
multirds_decoder_compare.block.yml
multirds_symbol_combiner.block.yml
multirds_rds_decoder_redsea.block.yml
multirds_variable_setter.block.yml
multirds_tmc_parser.block.yml
multirds_pilot_SNR.block.yml
multirds_stream_router.block.yml
DESTINATION share/gnuradio/grc/blocks
)

25
grc/multirds_decoder_compare.block.yml

@ -0,0 +1,25 @@
# auto-generated by grc.converter
id: multirds_decoder_compare
label: decoder_compare
category: '[multirds]'
parameters:
- id: nPorts
label: Number of Ports
dtype: int
default: '2'
hide: part
inputs:
- domain: message
id: in
multiplicity: ${ nPorts }
asserts:
- ${ nPorts > 0 }
templates:
imports: import multirds
make: multirds.decoder_compare(${nPorts})
file_format: 1

28
grc/multirds_decoder_compare.xml

@ -1,28 +0,0 @@
<?xml version="1.0"?>
<block>
<name>decoder_compare</name>
<key>multirds_decoder_compare</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.decoder_compare($nPorts)</make>
<!-- Make one 'param' node for every Parameter you want settable from the GUI.
Sub-nodes:
* name
* key (makes the value accessible as $keyname, e.g. in the make node)
* type -->
<param>
<name>Number of Ports</name>
<key>nPorts</key>
<value>2</value>
<type>int</type>
<hide>part</hide>
</param>
<check>$nPorts &gt; 0</check>
<sink>
<name>in</name>
<type>message</type>
<nports>$nPorts</nports>
<!-- <optional>1</optional> -->
</sink>
</block>

57
grc/multirds_pilot_SNR.block.yml

@ -0,0 +1,57 @@
# auto-generated by grc.converter
id: multirds_pilot_SNR
label: pilot_SNR
category: '[multirds]'
parameters:
- id: debug
label: Debug
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
- id: carrier_freq
label: carrier_freq
dtype: float
default: 19e3
- id: gap_width
label: gap_width
dtype: float
default: 4e3
- id: update_period
label: update_period
dtype: float
default: '0.2'
- id: samp_rate
label: samp_rate
dtype: int
default: '240000'
- id: fft_len
label: fft_len
dtype: int
default: '2048'
- id: msg_adr
label: msg_adr
dtype: int
default: '3'
inputs:
- domain: stream
dtype: float
vlen: ${ fft_len }
outputs:
- domain: message
id: out
optional: true
templates:
imports: import multirds
make: multirds.pilot_SNR(${debug}, ${samp_rate}, ${fft_len}, ${carrier_freq},${gap_width},
${msg_adr},${update_period})
documentation: |-
outputs PMT pair of longs (msg_adr . SNR) SNR is calculated as difference (in dB) between the 19k carrier power and the average power between carrier_freq-gap_width and carrier_freq+gap_width \
file_format: 1

84
grc/multirds_pilot_SNR.xml

@ -1,84 +0,0 @@
<?xml version="1.0"?>
<block>
<name>pilot_SNR</name>
<key>multirds_pilot_SNR</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.pilot_SNR($debug, $samp_rate, $fft_len, $carrier_freq,$gap_width, $msg_adr,$update_period)</make>
<!-- Make one 'param' node for every Parameter you want settable from the GUI.
Sub-nodes:
* name
* key (makes the value accessible as $keyname, e.g. in the make node)
* type -->
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>carrier_freq</name>
<key>carrier_freq</key>
<value>19e3</value>
<type>float</type>
</param>
<param>
<name>gap_width</name>
<key>gap_width</key>
<value>4e3</value>
<type>float</type>
</param>
<param>
<name>update_period</name>
<key>update_period</key>
<value>0.2</value>
<type>float</type>
</param>
<param>
<name>samp_rate</name>
<key>samp_rate</key>
<value>240000</value>
<type>int</type>
</param>
<param>
<name>fft_len</name>
<key>fft_len</key>
<value>2048</value>
<type>int</type>
</param>
<param>
<name>msg_adr</name>
<key>msg_adr</key>
<value>3</value>
<type>int</type>
</param>
<!-- Make one 'sink' node per input. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<sink>
<name>in</name>
<type>float</type>
<vlen>$fft_len</vlen>
</sink>
<source>
<name>out</name>
<type>message</type>
<optional>1</optional>
</source>
<doc>outputs PMT pair of longs (msg_adr . SNR) \
SNR is calculated as difference (in dB)\
between the 19k carrier power and the \
average power between carrier_freq-gap_width and carrier_freq+gap_width \
</doc>
</block>

136
grc/multirds_qtgui_range.xml

@ -1,136 +0,0 @@
<?xml version="1.0"?>
<block>
<name>qtgui_range (cr)</name>
<key>variable_multirds_qtgui_range</key>
<category>[multirds]</category>
<import>import multirds</import>
<import>from multirds.qtgui_range import qtgui_range, RangeWidget</import>
<var_make>self.$(id) = $(id) = $value</var_make>
<make>#set $win = 'self._%s_win'%$id
#set $range = 'self.%s_range'%$id
#if not $label()
#set $label = '"%s"'%$id
#end if
$(range) = qtgui_range($start, $stop, $step, $value, $min_len)
$(win) = RangeWidget($range, self.set_$(id), $label, "$widget", $rangeType)
$(gui_hint()($win))</make>
<!--<callback>self.freq2_range.set_test($value);</callback>-->
<!-- <callback>self.set_$(id)($value)</callback> -->
<!-- <callback>set_test($(id));</callback> -->
<!-- <callback>self._$(id)_win.set_test($(id));</callback>-->
<param>
<name>Label</name>
<key>label</key>
<value></value>
<type>string</type>
<hide>#if $label() then 'none' else 'part'#</hide>
</param>
<param>
<name>Type</name>
<key>rangeType</key>
<value>"float"</value>
<type>enum</type>
<hide>part</hide>
<option><name>Float</name><key>float</key><opt>type:float</opt></option>
<option><name>Int</name><key>int</key><opt>type:int</opt></option>
</param>
<param>
<name>Default Value</name>
<key>value</key>
<value>50</value>
<type>$rangeType.type</type>
</param>
<param>
<name>Start</name>
<key>start</key>
<value>0</value>
<type>$rangeType.type</type>
</param>
<param>
<name>Stop</name>
<key>stop</key>
<value>100</value>
<type>$rangeType.type</type>
</param>
<param>
<name>Step</name>
<key>step</key>
<value>1</value>
<type>$rangeType.type</type>
</param>
<param>
<name>Widget</name>
<key>widget</key>
<value>counter_slider</value>
<type>enum</type>
<hide>part</hide>
<option><name>Counter + Slider</name><key>counter_slider</key></option>
<option><name>Counter</name><key>counter</key></option>
<option><name>Slider</name><key>slider</key></option>
<option><name>Knob</name><key>dial</key></option>
</param>
<param>
<name>Orientation</name>
<key>orient</key>
<value>Qt.Horizontal</value>
<type>enum</type>
<hide>#if $widget() == "slider" then 'part' else 'all'#</hide>
<option>
<name>Horizontal</name>
<key>Qt.Horizontal</key>
<opt>scalepos:BottomScale</opt>
<opt>minfcn:setMinimumWidth</opt>
</option>
<option>
<name>Vertical</name>
<key>Qt.Vertical</key>
<opt>scalepos:LeftScale</opt>
<opt>minfcn:setMinimumHeight</opt>
</option>
</param>
<param>
<name>Minimum Length</name>
<key>min_len</key>
<value>200</value>
<type>int</type>
<hide>part</hide>
</param>
<!-- from min_len <hide>#if $widget().split('_')[0] in ("slider", "counter") then 'part' else 'all'#</hide>-->
<param>
<name>GUI Hint</name>
<key>gui_hint</key>
<value></value>
<type>gui_hint</type>
<hide>part</hide>
</param>
<check>$start &lt;= $value &lt;= $stop</check>
<check>$start &lt; $stop</check>
<!-- <sink>
<name>set</name>
<type>message</type>
<optional>1</optional>
</sink>-->
<doc>
This block creates a variable with a slider. \
Leave the label blank to use the variable id as the label. \
The value must be a real number. \
The value must be between the start and the stop.
The GUI hint can be used to position the widget within the application. \
The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. \
Both the tab specification and the grid position are optional.
</doc>
</block>

23
grc/multirds_rds_decoder.block.yml

@ -0,0 +1,23 @@
# auto-generated by grc.converter
id: multirds_rds_decoder
label: Rds decoder
category: '[MULTIRDS]'
parameters:
- id: log
label: Log
dtype: raw
- id: debug
label: Debug
dtype: raw
inputs:
- domain: stream
dtype: byte
templates:
imports: import multirds
make: multirds.rds_decoder(${log}, ${debug})
file_format: 1

45
grc/multirds_rds_decoder.xml

@ -1,45 +0,0 @@
<?xml version="1.0"?>
<block>
<name>RDS Decoder (cr)</name>
<key>multirds_rds_decoder</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.rds_decoder($log, $debug)</make>
<param>
<name>Log</name>
<key>log</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<sink>
<name>in</name>
<type>byte</type>
</sink>
<source>
<name>out</name>
<type>message</type>
<optional>1</optional>
</source>
</block>

23
grc/multirds_rds_decoder_redsea.block.yml

@ -0,0 +1,23 @@
# auto-generated by grc.converter
id: multirds_rds_decoder_redsea
label: Rds decoder redsea
category: '[MULTIRDS]'
parameters:
- id: log
label: Log
dtype: raw
- id: debug
label: Debug
dtype: raw
inputs:
- domain: stream
dtype: byte
templates:
imports: import multirds
make: multirds.rds_decoder_redsea(${log}, ${debug})
file_format: 1

45
grc/multirds_rds_decoder_redsea.xml

@ -1,45 +0,0 @@
<?xml version="1.0"?>
<block>
<name>RDS Decoder (redsea)</name>
<key>multirds_rds_decoder_redsea</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.rds_decoder_redsea($log, $debug)</make>
<param>
<name>Log</name>
<key>log</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<sink>
<name>in</name>
<type>byte</type>
</sink>
<source>
<name>out</name>
<type>message</type>
<optional>1</optional>
</source>
</block>

86
grc/multirds_rds_parser_table_qt.block.yml

@ -0,0 +1,86 @@
# auto-generated by grc.converter
id: multirds_rds_parser_table_qt
label: RDS Parser Table (qt)
category: '[multirds]'
parameters:
- id: freq_tune
label: tuned frequency
dtype: float
- id: label
label: Label
dtype: string
hide: ${ ('none' if label else 'part') }
- id: workdir
label: work directory
dtype: string
hide: part
- id: gui_hint
label: GUI Hint
dtype: gui_hint
hide: part
- id: nPorts
label: Number of Ports
dtype: int
default: '2'
hide: part
- id: log
label: Log
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
- id: debug
label: Debug
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
- id: writeDB
label: write Database
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
inputs:
- domain: message
id: in
multiplicity: ${ nPorts }
- domain: message
id: freq
optional: true
outputs:
- domain: message
id: ctrl
optional: true
- domain: message
id: tmc_raw
optional: true
asserts:
- ${ open(workdir+"pty-list.csv").close() or True }
- ${ open(workdir+"directory_writable","w").close() or True }
- ${ nPorts > 0 }
templates:
imports: |-
import multirds
from multirds.rds_parser_table_qt import rds_parser_table_qt, rds_parser_table_qt_Widget,rds_parser_table_qt_Signals
make: "<% win = 'self._%s_win'%id %>\n\t\t<% signals = 'self._%s_signals'%id %>\n\
% if not label:\n\t<% label = '\"%s\"'%id %>\n% endif\n${signals} = rds_parser_table_qt_Signals()\n\
self.${id} = multirds.rds_parser_table_qt(${signals},${nPorts},self.set_${freq_tune},${freq_tune},${log},\
\ ${debug},${workdir},${writeDB})\n${win} = rds_parser_table_qt_Widget(${signals},\
\ ${label},self.${id})\n${gui_hint(in)}"
callbacks:
- set_freq_tune(${freq_tune});
documentation: "show RDS data from multiple stations in QT table input: raw group\
\ data (array of ints) 4x2 raw block data, 4x1 offset chars, 1x1 number of valid\
\ blocks (of last 50) [block1_upper,block1_lower,block2_upper,block2_lower,...,offset1,offset2,offset3,offset4,numerrors]\\\
\ \n 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."
file_format: 1

141
grc/multirds_rds_parser_table_qt.xml

@ -1,141 +0,0 @@
<?xml version="1.0"?>
<block>
<name>RDS Parser Table (qt)</name>
<key>multirds_rds_parser_table_qt</key>
<category>[multirds]</category>
<import>import multirds</import>
<import>from multirds.rds_parser_table_qt import rds_parser_table_qt, rds_parser_table_qt_Widget,rds_parser_table_qt_Signals</import>
<!--
<var_make>self.$(id) = $(id) = $value</var_make>
-->
<make>#set $win = 'self._%s_win'%$id
#set $signals = 'self._%s_signals'%$id
#if not $label()
#set $label = '"%s"'%$id
#end if
$(signals) = rds_parser_table_qt_Signals()
self.$(id) = multirds.rds_parser_table_qt($(signals),$nPorts,self.set_$(freq_tune),$freq_tune,$log, $debug,$workdir,$writeDB)
$(win) = rds_parser_table_qt_Widget($signals, $label,self.$(id))
$(gui_hint()($win))</make>
<callback>set_freq_tune($freq_tune);</callback>
<param>
<name>tuned frequency</name>
<key>freq_tune</key>
<value></value>
<type>float</type>
</param>
<param>
<name>Label</name>
<key>label</key>
<value></value>
<type>string</type>
<hide>#if $label() then 'none' else 'part'#</hide>
</param>
<param>
<name>work directory</name>
<key>workdir</key>
<value></value>
<type>string</type>
<hide>part</hide>
</param>
<param>
<name>GUI Hint</name>
<key>gui_hint</key>
<value></value>
<type>gui_hint</type>
<hide>part</hide>
</param>
<param>
<name>Number of Ports</name>
<key>nPorts</key>
<value>2</value>
<type>int</type>
<hide>part</hide>
</param>
<param>
<name>Log</name>
<key>log</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>write Database</name>
<key>writeDB</key>
<value>False</value>
<type>bool</type>
<!--<hide>part</hide>-->
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<!--
check if pty list file exists
check directory doesnt work:
<check>os.path.isdir($workdir)</check>
-->
<check>open($workdir+"pty-list.csv").close() or True</check>
<!--
check if workdir is writable
-->
<check>open($workdir+"directory_writable","w").close() or True</check>
<check>$nPorts &gt; 0</check>
<sink>
<name>in</name>
<type>message</type>
<nports>$nPorts</nports>
<!-- <optional>1</optional> -->
</sink>
<sink>
<name>freq</name>
<type>message</type>
<optional>1</optional>
</sink>
<source>
<name>ctrl</name>
<type>message</type>
<optional>1</optional>
</source>
<source>
<name>tmc_raw</name>
<type>message</type>
<optional>1</optional>
</source>
<doc>show RDS data from multiple stations in QT table \
input: raw group data (array of ints) \
4x2 raw block data, 4x1 offset chars, 1x1 number of valid blocks (of last 50) \
[block1_upper,block1_lower,block2_upper,block2_lower,...,offset1,offset2,offset3,offset4,numerrors]\\
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>

37
grc/multirds_rds_table_qt.block.yml

@ -0,0 +1,37 @@
# auto-generated by grc.converter
id: multirds_rds_table_qt
label: RDS Table (qt)
category: '[multirds]'
parameters:
- id: label
label: Label
dtype: string
hide: ${ ('none' if label else 'part') }
- id: gui_hint
label: GUI Hint
dtype: gui_hint
hide: part
- id: nPorts
label: Number of Ports
dtype: int
default: '2'
hide: part
inputs:
- domain: message
id: in
multiplicity: ${ nPorts }
templates:
imports: |-
import multirds
from multirds.rds_table_qt import rds_table_qt, rds_table_qt_Widget,rds_table_qt_Signals
var_make: self.${id} = ${id} = ${value}
make: "<% win = 'self._%s_win'%id %>\n\t\t<% signals = 'self._%s_signals'%id %>\n\
% if not label:\n\t<% label = '\"%s\"'%id %>\n% endif\n${signals} = rds_table_qt_Signals()\n\
self.${id} = multirds.rds_table_qt(${signals},${nPorts})\n${win} = rds_table_qt_Widget(${signals},\
\ ${label})\n${gui_hint(in)}"
file_format: 1

46
grc/multirds_rds_table_qt.xml

@ -1,46 +0,0 @@
<?xml version="1.0"?>
<block>
<name>RDS Table (qt)</name>
<key>multirds_rds_table_qt</key>
<category>[multirds]</category>
<import>import multirds</import>
<import>from multirds.rds_table_qt import rds_table_qt, rds_table_qt_Widget,rds_table_qt_Signals</import>
<var_make>self.$(id) = $(id) = $value</var_make>
<make>#set $win = 'self._%s_win'%$id
#set $signals = 'self._%s_signals'%$id
#if not $label()
#set $label = '"%s"'%$id
#end if
$(signals) = rds_table_qt_Signals()
self.$(id) = multirds.rds_table_qt($(signals),$nPorts)
$(win) = rds_table_qt_Widget($signals, $label)
$(gui_hint()($win))</make>
<param>
<name>Label</name>
<key>label</key>
<value></value>
<type>string</type>
<hide>#if $label() then 'none' else 'part'#</hide>
</param>
<param>
<name>GUI Hint</name>
<key>gui_hint</key>
<value></value>
<type>gui_hint</type>
<hide>part</hide>
</param>
<param>
<name>Number of Ports</name>
<key>nPorts</key>
<value>2</value>
<type>int</type>
<hide>part</hide>
</param>
<sink>
<name>in</name>
<type>message</type>
<nports>$nPorts</nports>
<!--<optional>1</optional>-->
</sink>
</block>

52
grc/multirds_station_search.block.yml

@ -0,0 +1,52 @@
# auto-generated by grc.converter
id: multirds_station_search
label: station_search
category: '[multirds]'
parameters:
- id: fft_len
label: fft lenngth
dtype: int
hide: ${ 'part' if vlen == 1 else 'none' }
- id: round_to
label: round to (in hz)
dtype: int
- id: num_decoders
label: number of decoders
dtype: int
hide: part
- id: center_freq
label: center frequency
dtype: float
- id: samp_rate
label: sample rate
dtype: int
- id: debug
label: Debug
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
hide: part
inputs:
- domain: stream
dtype: float
vlen: ${ fft_len }
- domain: message
id: ctrl
optional: true
outputs:
- domain: message
id: out
optional: true
templates:
imports: import multirds
make: multirds.station_search(${fft_len}, ${num_decoders}, ${center_freq}, ${samp_rate},${round_to},${debug})
callbacks:
- set_center_freq(${center_freq});
file_format: 1

78
grc/multirds_station_search.xml

@ -1,78 +0,0 @@
<?xml version="1.0"?>
<block>
<name>station_search</name>
<key>multirds_station_search</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.station_search($fft_len, $num_decoders, $center_freq, $samp_rate,$round_to,$debug)</make>
<!-- Make one 'param' node for every Parameter you want settable from the GUI.
Sub-nodes:
* name
* key (makes the value accessible as $keyname, e.g. in the make node)
* type -->
<callback>set_center_freq($center_freq);</callback>
<param>
<name>fft lenngth</name>
<key>fft_len</key>
<type>int</type>
</param>
<param>
<name>round to (in hz)</name>
<key>round_to</key>
<type>int</type>
</param>
<param>
<name>number of decoders</name>
<key>num_decoders</key>
<type>int</type>
<hide>part</hide>
</param>
<param>
<name>center frequency</name>
<key>center_freq</key>
<type>float</type>
</param>
<param>
<name>sample rate</name>
<key>samp_rate</key>
<type>int</type>
</param>
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<hide>part</hide>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<!-- Make one 'sink' node per input. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<sink>
<name>in</name>
<type>float</type>
<vlen>$fft_len</vlen>
</sink>
<sink>
<name>ctrl</name>
<type>message</type>
<optional>1</optional>
</sink>
<source>
<name>out</name>
<type>message</type>
<optional>1</optional>
</source>
</block>

29
grc/multirds_stream_router.block.yml

@ -0,0 +1,29 @@
# auto-generated by grc.converter
id: multirds_stream_router
label: Stream router
category: '[MULTIRDS]'
parameters:
- id: ninputs
label: Ninputs
dtype: int
- id: noutputs
label: Noutputs
dtype: int
inputs:
- domain: stream
dtype: float
multiplicity: '9'
outputs:
- domain: stream
dtype: float
multiplicity: '3'
templates:
imports: import multirds
make: multirds.stream_router(${ninputs}, ${noutputs})
file_format: 1

54
grc/multirds_stream_router.xml

@ -1,54 +0,0 @@
<?xml version="1.0"?>
<block>
<name>stream_router</name>
<key>multirds_stream_router</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.stream_router($ninputs, $noutputs)</make>
<param>
<name>Type</name>
<key>type</key>
<value>float</value>
<type>enum</type>
<option><name>Complex</name><key>complex</key><opt>fcn:sink_c</opt></option>
<option><name>Float</name><key>float</key><opt>fcn:sink_f</opt></option>
</param>
<param>
<name>Number of inputs</name>
<key>ninputs</key>
<value>9</value>
<type>int</type>
</param>
<param>
<name>Number of outputs</name>
<key>noutputs</key>
<value>3</value>
<type>int</type>
</param>
<!-- Make one 'sink' node per input. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<sink>
<name>in</name>
<type>$type</type>
<nports>$ninputs</nports>
</sink>
<sink>
<name>ctrl</name>
<type>message</type>
</sink>
<!-- Make one 'source' node per output. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<source>
<name>out</name>
<type>$type</type>
<nports>$noutputs</nports>
</source>
</block>

30
grc/multirds_stream_selector.block.yml

@ -0,0 +1,30 @@
# auto-generated by grc.converter
id: multirds_stream_selector
label: stream_selector
category: '[multirds]'
inputs:
- label: in_re
domain: stream
dtype: float
- label: in_arg
domain: stream
dtype: float
- domain: message
id: rds_re
optional: true
- domain: message
id: rds_arg
optional: true
outputs:
- domain: message
id: rds_out
optional: true
templates:
imports: import multirds
make: multirds.stream_selector()
file_format: 1

38
grc/multirds_stream_selector.xml

@ -1,38 +0,0 @@
<?xml version="1.0"?>
<block>
<name>stream_selector</name>
<key>multirds_stream_selector</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.stream_selector()</make>
<!-- <param>
<name>...</name>
<key>...</key>
<type>...</type>
</param>-->
<sink>
<name>in_re</name>
<type>float</type>
</sink>
<sink>
<name>in_arg</name>
<type>float</type>
</sink>
<sink>
<name>rds_re</name>
<type>message</type>
<optional>1</optional>
</sink>
<sink>
<name>rds_arg</name>
<type>message</type>
<optional>1</optional>
</sink>
<source>
<name>rds_out</name>
<type>message</type>
<optional>1</optional>
</source>
</block>

30
grc/multirds_symbol_combiner.block.yml

@ -0,0 +1,30 @@
# auto-generated by grc.converter
id: multirds_symbol_combiner
label: Symbol combiner
category: '[MULTIRDS]'
parameters:
- id: threshold
label: Threshold
dtype: float
- id: min_diff
label: Min_diff
dtype: float
- id: log
label: Log
dtype: raw
inputs:
- domain: stream
dtype: float
outputs:
- domain: stream
dtype: float
templates:
imports: import multirds
make: multirds.symbol_combiner(${threshold}, ${min_diff}, ${log})
file_format: 1

70
grc/multirds_symbol_combiner.xml

@ -1,70 +0,0 @@
<?xml version="1.0"?>
<block>
<name>symbol_combiner</name>
<key>multirds_symbol_combiner</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.symbol_combiner($threshold, $min_diff, $log)</make>
<!-- Make one 'param' node for every Parameter you want settable from the GUI.
Sub-nodes:
* name
* key (makes the value accessible as $keyname, e.g. in the make node)
* type -->
<param>
<name>Log</name>
<key>log</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>Threshold</name>
<key>threshold</key>
<value>0.25</value>
<type>float</type>
</param>
<param>
<name>min_diff</name>
<key>min_diff</key>
<value>0.2</value>
<type>float</type>
</param>
<check>0 &lt; $min_diff &lt; 1</check>
<!-- Make one 'sink' node per input. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<sink>
<name>in</name>
<type>float</type>
</sink>
<sink>
<name>ctrl</name>
<type>message</type>
<optional>1</optional>
</sink>
<!-- Make one 'source' node per output. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<source>
<name>ctrl</name>
<type>message</type>
<optional>1</optional>
</source>
<source>
<name>out</name>
<type>float</type>
</source>
</block>

62
grc/multirds_tmc_parser.block.yml

@ -0,0 +1,62 @@
# auto-generated by grc.converter
id: multirds_tmc_parser
label: tmc_parser
category: '[multirds]'
parameters:
- id: maxheight
label: maxheight
dtype: int
default: '160'
hide: part
- id: workdir
label: work directory
dtype: string
hide: part
- id: label
label: Label
dtype: string
hide: ${ ('none' if label else 'part') }
- id: log
label: Log
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
- id: debug
label: Debug
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
- id: writeDB
label: write Database
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
- id: gui_hint
label: GUI Hint
dtype: gui_hint
hide: part
inputs:
- domain: message
id: in
optional: true
asserts:
- ${ open(workdir+"event-list_with_forecast_sort.csv").close() or True }
- ${ open(workdir+"directory_writable","w").close() or True }
templates:
imports: import multirds
make: "<% win = 'self._%s_win'%id %>\n <% parser = 'self.%s_parser'%id\
\ %>\n% if not label:\n\t<% label = '\"%s\"'%id %>\n% endif\n${parser} = multirds.tmc_parser(${workdir},\
\ ${log}, ${debug}, ${writeDB},${maxheight})\n${win} = ${parser}.getqtwidget()\n\
${gui_hint(in)}\n "
documentation: "maxheight = max height of widget in pixels\n\t maxheight == 0 ->\
\ no restriction"
file_format: 1

112
grc/multirds_tmc_parser.xml

@ -1,112 +0,0 @@
<?xml version="1.0"?>
<block>
<name>tmc_parser</name>
<key>multirds_tmc_parser</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>#set $win = 'self._%s_win'%$id
#set $parser = 'self.%s_parser'%$id
#if not $label()
#set $label = '"%s"'%$id
#end if
$(parser) = multirds.tmc_parser($workdir, $log, $debug, $writeDB,$maxheight)
$(win) = $(parser).getqtwidget()
$(gui_hint()($win))
</make>
<!--
multirds.tmc_parser($workdir, $log, $debug, $writeDB)
-->
<param>
<name>maxheight</name>
<key>maxheight</key>
<value>160</value>
<type>int</type>
<hide>part</hide>
</param>
<param>
<name>work directory</name>
<key>workdir</key>
<value></value>
<type>string</type>
<hide>part</hide>
</param>
<param>
<name>Label</name>
<key>label</key>
<value></value>
<type>string</type>
<hide>#if $label() then 'none' else 'part'#</hide>
</param>
<param>
<name>Log</name>
<key>log</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>write Database</name>
<key>writeDB</key>
<value>False</value>
<type>bool</type>
<!--<hide>part</hide>-->
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>GUI Hint</name>
<key>gui_hint</key>
<value></value>
<type>gui_hint</type>
<hide>part</hide>
</param>
<!--
check if event-list file exists
check directory doesnt work:
<check>os.path.isdir($workdir)</check>
-->
<check>open($workdir+"event-list_with_forecast_sort.csv").close() or True</check>
<!--
check if workdir is writable
-->
<check>open($workdir+"directory_writable","w").close() or True</check>
<sink>
<name>in</name>
<type>message</type>
<optional>1</optional>
</sink>
<doc>
maxheight = max height of widget in pixels
maxheight == 0 -> no restriction
</doc>
</block>

37
grc/multirds_variable_setter.block.yml

@ -0,0 +1,37 @@
# auto-generated by grc.converter
id: multirds_variable_setter
label: variable_setter
category: '[multirds]'
parameters:
- id: varname
label: varname
dtype: raw
- id: is_pair
label: Pair Mode
dtype: enum
default: 'False'
options: ['False', 'True']
- id: msgkey
label: Key
dtype: string
hide: ${ ('none' if is_pair == 'True' else 'all') }
inputs:
- domain: message
id: in
templates:
imports: import multirds
make: |-
<% block = 'self.%s'%id %>
<% varsetter = 'self.set_%s'%varname %>
<% guiupdater = 'self._%s_win.update_gui'%varname %>
multirds.variable_setter("$varname",${varsetter},${guiupdater},${is_pair},${msgkey})
documentation: |-
in pair mode this block only accepts PMT pairs that have a matching CAR
no pair mode: block accepts pmt symbols directly
file_format: 1

59
grc/multirds_variable_setter.xml

@ -1,59 +0,0 @@
<?xml version="1.0"?>
<block>
<name>variable_setter</name>
<key>multirds_variable_setter</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>#set $block = 'self.%s'%$id
#set $varsetter = 'self.set_%s'%$varname
#set $guiupdater = 'self._%s_win.update_gui'%$varname
multirds.variable_setter("$varname",$varsetter,$guiupdater,$is_pair,$msgkey)</make>
<!--$(block) = multirds.variable_setter($varname,$varsetter) -->
<param>
<name>varname</name>
<key>varname</key>
<value></value>
<type>raw</type>
</param>
<param>
<name>Pair Mode</name>
<key>is_pair</key>
<value>False</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>msgkey</key>
<value></value>
<type>string</type>
<hide>#if $is_pair() == 'True' then 'none' else 'all'#</hide>
</param>
<!-- Make one 'sink' node per input. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<sink>
<name>in</name>
<type>message</type>
</sink>
<!-- Make one 'source' node per output. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<doc>
in pair mode this block only accepts PMT pairs that have a matching CAR
no pair mode: block accepts pmt symbols directly
</doc>
</block>

55
grc/multirds_vector_cutter.block.yml

@ -0,0 +1,55 @@
# auto-generated by grc.converter
id: multirds_vector_cutter
label: vector_cutter
category: '[multirds]'
parameters:
- id: pad_out
label: padded output
dtype: enum
default: 'False'
options: ['True', 'False']
option_labels: ['Yes', 'No']
hide: part
- id: zero_len
label: num-zeros
dtype: int
default: '0'
- id: insize
label: insize
dtype: int
default: '2048'
- id: outsize
label: outsize
dtype: int
default: '1024'
- id: cutpoint
label: cutpoint
dtype: int
default: '512'
inputs:
- domain: stream
dtype: complex
vlen: ${ insize }
outputs:
- domain: stream
dtype: complex
vlen: ${ outsize }
- label: out_padded
domain: stream
dtype: complex
vlen: ${ insize }
optional: true
hide: ${ ('False' if pad_out == 'True' else 'True') }
templates:
imports: import multirds
make: multirds.vector_cutter(${insize}, ${outsize}, ${cutpoint},${pad_out},${zero_len})
callbacks:
- set_cutpoint(${cutpoint});
- set_zero_len(${zero_len});
file_format: 1

87
grc/multirds_vector_cutter.xml

@ -1,87 +0,0 @@
<?xml version="1.0"?>
<block>
<name>vector_cutter</name>
<key>multirds_vector_cutter</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.vector_cutter($insize, $outsize, $cutpoint,$pad_out,$zero_len)</make>
<!-- Make one 'param' node for every Parameter you want settable from the GUI.
Sub-nodes:
* name
* key (makes the value accessible as $keyname, e.g. in the make node)
* type -->
<callback>set_cutpoint($cutpoint);</callback>
<callback>set_zero_len($zero_len);</callback>
<!-- <param>
<name>padded output</name>
<key>pad_out</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>-->
<param>
<name>padded output</name>
<key>pad_out</key>
<value>False</value>
<type>enum</type>
<hide>part</hide>
<option>
<name>Yes</name>
<key>True</key>
</option>
<option>
<name>No</name>
<key>False</key>
</option>
</param>
<param>
<name>num-zeros</name>
<key>zero_len</key>
<value>0</value>
<type>int</type>
</param>
<param>
<name>insize</name>
<key>insize</key>
<value>2048</value>
<type>int</type>
</param>
<param>
<name>outsize</name>
<key>outsize</key>
<value>1024</value>
<type>int</type>
</param>
<param>
<name>cutpoint</name>
<key>cutpoint</key>
<value>512</value>
<type>int</type>
</param>
<sink>
<name>in</name>
<type>complex</type>
<vlen>$insize</vlen>
</sink>
<source>
<name>out</name>
<type>complex</type>
<vlen>$outsize</vlen>
</source>
<source>
<name>out_padded</name>
<type>complex</type>
<vlen>$insize</vlen>
<optional>#if $pad_out() == 'True' then 'False' else 'True'#</optional>
<!--<optional>#if $pad_out==True then '1' else '0'#</optional>-->
<hide>#if $pad_out() == 'True' then 'False' else 'True'#</hide>
</source>
</block>

4
python/CMakeLists.txt

@ -38,11 +38,11 @@ GR_PYTHON_INSTALL(
stream_selector.py
vector_cutter.py
decoder_compare.py
qtgui_range.py
variable_setter.py
tmc_classes.py
tmc_parser.py
pilot_SNR.py DESTINATION ${GR_PYTHON_DIR}/multirds
pilot_SNR.py
DESTINATION ${GR_PYTHON_DIR}/multirds
)
########################################################################

25
python/__init__.py

@ -33,16 +33,17 @@ except ImportError:
# import any pure python here
from rds_table_qt import rds_table_qt
from rds_parser_table_qt import rds_parser_table_qt
from station_search import station_search
from chart import Chart
from stream_selector import stream_selector
from vector_cutter import vector_cutter
from decoder_compare import decoder_compare
from qtgui_range import qtgui_range
from variable_setter import variable_setter
from tmc_parser import tmc_parser
from pilot_SNR import pilot_SNR
from .rds_table_qt import rds_table_qt
from .rds_parser_table_qt import rds_parser_table_qt
from .station_search import station_search
from .chart import Chart
from .stream_selector import stream_selector
from .vector_cutter import vector_cutter
from .decoder_compare import decoder_compare
from .variable_setter import variable_setter
from .tmc_parser import tmc_parser
from .pilot_SNR import pilot_SNR
#

279
python/qtgui_range.py

@ -1,279 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2015 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
from PyQt4 import Qt, QtCore, QtGui
import pmt
from gnuradio import gr
class qtgui_range(gr.basic_block):
def set_test(self,value):
print("test callback invoked")
print(value)
def __init__(self, minv, maxv, step, default, min_length):
gr.basic_block.__init__(self,
name="qtgui_range",
in_sig=None,
out_sig=None)
self.min = float(minv)
self.max = float(maxv)
self.step = float(step)
self.default = float(default)
self.min_length = min_length
self.find_precision()
self.find_nsteps()
def find_precision(self):
# Get the decimal part of the step
temp = str(float(self.step) - int(self.step))[2:]
precision = len(temp) if temp is not '0' else 0
precision = min(precision, 13)
if precision == 0 and self.max < 100:
self.precision = 1 # Always have a decimal in this case
else:
self.precision = (precision + 2) if precision > 0 else 0
def find_nsteps(self):
self.nsteps = (self.max + self.step - self.min)/self.step
def demap_range(self, val):
if val > self.max:
val = self.max
if val < self.min:
val = self.min
return ((val-self.min)/self.step)
def map_range(self, val):
if val > self.nsteps:
val = self.max
if val < 0:
val = 0
return (val*self.step+self.min)
class RangeWidget(QtGui.QWidget):
def update_gui(self,value):
#print("update_gui called on widget %s"%self.label)
#print(value)
#self.d_widget.slider.setValue(value)
if self.range.min < value < self.range.max:
if self.style=="counter_slider":
self.d_widget.counter.setValue(value)
else:
self.d_widget.setValue(value)
else:
print("value %i not in range %i...%i"%(value,self.range.min,self.range.max))
#self.notifyChanged(self.rangeType(value))
def __init__(self, ranges, slot, label, style, rangeType=float):
""" Creates the QT Range widget """
QtGui.QWidget.__init__(self)
self.range = ranges
self.style = style
self.label=label
# rangeType tells the block how to return the value as a standard
self.rangeType = rangeType
# Top-block function to call when any value changes
# Some widgets call this directly when their value changes.
# Others have intermediate functions to map the value into the right range.
self.notifyChanged = slot
layout = Qt.QHBoxLayout()
label = Qt.QLabel(label)
layout.addWidget(label)
if style == "dial":
self.d_widget = self.Dial(self, self.range, self.notifyChanged, rangeType)
elif style == "slider":
self.d_widget = self.Slider(self, self.range, self.notifyChanged, rangeType)
elif style == "counter":
# The counter widget can be directly wired to the notifyChanged slot
self.d_widget = self.Counter(self, self.range, self.notifyChanged, rangeType)
else:
# The CounterSlider needs its own internal handlers before calling notifyChanged
self.d_widget = self.CounterSlider(self, self.range, self.notifyChanged, rangeType)
layout.addWidget(self.d_widget)
self.setLayout(layout)
class Dial(QtGui.QDial):
""" Creates the range using a dial """
def __init__(self, parent, ranges, slot, rangeType=float):
QtGui.QDial.__init__(self, parent)
self.rangeType = rangeType
# Setup the dial
self.setRange(0, ranges.nsteps-1)
self.setSingleStep(1)
self.setNotchesVisible(True)
self.range = ranges
# Round the initial value to the closest tick
temp = int(round(ranges.demap_range(ranges.default), 0))
self.setValue(temp)
# Setup the slots
self.valueChanged.connect(self.changed)
self.notifyChanged = slot
def changed(self, value):
""" Handles maping the value to the right range before calling the slot. """
val = self.range.map_range(value)
self.notifyChanged(self.rangeType(val))
class Slider(QtGui.QSlider):
""" Creates the range using a slider """
def __init__(self, parent, ranges, slot, rangeType=float):
QtGui.QSlider.__init__(self, QtCore.Qt.Horizontal, parent)
self.rangeType = rangeType
# Setup the slider
#self.setFocusPolicy(QtCore.Qt.NoFocus)
self.setRange(0, ranges.nsteps - 1)
self.setTickPosition(2)
self.setSingleStep(1)
self.range = ranges
# Round the initial value to the closest tick
temp = int(round(ranges.demap_range(ranges.default), 0))
self.setValue(temp)
if ranges.nsteps > ranges.min_length:
interval = int(ranges.nsteps/ranges.min_length)
self.setTickInterval(interval)
self.setPageStep(interval)
else:
self.setTickInterval(1)
self.setPageStep(1)
# Setup the handler function
self.valueChanged.connect(self.changed)
self.notifyChanged = slot
def changed(self, value):
""" Handle the valueChanged signal and map the value into the correct range """
val = self.range.map_range(value)
self.notifyChanged(self.rangeType(val))
def mousePressEvent(self, event):
if((event.button() == QtCore.Qt.LeftButton)):
new = self.minimum() + ((self.maximum()-self.minimum()) * event.x()) / self.width()
self.setValue(new)
event.accept()
# Use repaint rather than calling the super mousePressEvent.
# Calling super causes issue where slider jumps to wrong value.
QtGui.QSlider.repaint(self)
def mouseMoveEvent(self, event):
new = self.minimum() + ((self.maximum()-self.minimum()) * event.x()) / self.width()
self.setValue(new)
event.accept()
QtGui.QSlider.repaint(self)
class Counter(QtGui.QDoubleSpinBox):
""" Creates the range using a counter """
def __init__(self, parent, ranges, slot, rangeType=float):
QtGui.QDoubleSpinBox.__init__(self, parent)
self.rangeType = rangeType
# Setup the counter
self.setRange(ranges.min, ranges.max)
self.setValue(ranges.default)
self.setSingleStep(ranges.step)
self.setKeyboardTracking(False)
self.setDecimals(ranges.precision)
# The counter already handles floats and can be connected directly.
self.valueChanged.connect(self.changed)
self.notifyChanged = slot
def changed(self, value):
""" Handle the valueChanged signal by converting to the right type """
self.notifyChanged(self.rangeType(value))
class CounterSlider(QtGui.QWidget):
""" Creates the range using a counter and slider """
def __init__(self, parent, ranges, slot, rangeType=float):
QtGui.QWidget.__init__(self, parent)
self.rangeType = rangeType
# Slot to call in the parent
self.notifyChanged = slot
self.slider = RangeWidget.Slider(parent, ranges, self.sliderChanged, rangeType)
self.counter = RangeWidget.Counter(parent, ranges, self.counterChanged, rangeType)
# Need another horizontal layout to wrap the other widgets.
layout = Qt.QHBoxLayout()
layout.addWidget(self.slider)
layout.addWidget(self.counter)
self.setLayout(layout)
# Flag to ignore the slider event caused by a change to the counter.
self.ignoreSlider = False
self.range = ranges
def sliderChanged(self, value):
""" Handles changing the counter when the slider is updated """
# If the counter was changed, ignore any of these events
if not self.ignoreSlider:
# Value is already float. Just set the counter
self.counter.setValue(self.rangeType(value))
self.notifyChanged(self.rangeType(value))
self.ignoreSlider = False
def counterChanged(self, value):
""" Handles changing the slider when the counter is updated """
# Get the current slider value and check to see if the new value changes it
current = self.slider.value()
new = int(round(self.range.demap_range(value), 0))
# If it needs to change, ignore the slider event
# Otherwise, the slider will cause the counter to round to the nearest tick
if current != new:
self.ignoreSlider = True
self.slider.setValue(new)
self.notifyChanged(self.rangeType(value))
if __name__ == "__main__":
from PyQt4 import Qt
import sys
def valueChanged(frequency):
print("Value updated - " + str(frequency))
app = Qt.QApplication(sys.argv)
widget = RangeWidget(qtgui_range(0, 100, 10, 1, 100), valueChanged, "Test", "counter_slider", int)
widget.show()
widget.setWindowTitle("Test Qt Range")
app.exec_()
widget = None
Loading…
Cancel
Save