summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/grc_gr_qtgui.m43
-rw-r--r--gr-qtgui/Makefile.am1
-rw-r--r--gr-qtgui/grc/Makefile.am3
-rw-r--r--gr-qtgui/grc/qtgui_sink_x.xml18
-rw-r--r--gr-qtgui/grc/qtgui_tab_widget.xml84
-rw-r--r--gr-qtgui/grc/qtgui_variable_slider.xml30
-rw-r--r--grc/blocks/options.xml2
-rw-r--r--grc/python/Generator.py4
-rw-r--r--grc/python/Param.py25
-rw-r--r--grc/python/flow_graph.tmpl13
10 files changed, 161 insertions, 22 deletions
diff --git a/config/grc_gr_qtgui.m4 b/config/grc_gr_qtgui.m4
index 4027bb332..c14f984c3 100644
--- a/config/grc_gr_qtgui.m4
+++ b/config/grc_gr_qtgui.m4
@@ -1,4 +1,4 @@
-dnl Copyright 2001,2002,2003,2004,2005,2006,2008 Free Software Foundation, Inc.
+dnl Copyright 2001,2002,2003,2004,2005,2006,2008,2011 Free Software Foundation, Inc.
dnl
dnl This file is part of GNU Radio
dnl
@@ -82,6 +82,7 @@ AC_DEFUN([GRC_GR_QTGUI],[
AC_CONFIG_FILES([ \
gr-qtgui/Makefile \
+ gr-qtgui/grc/Makefile \
gr-qtgui/src/Makefile \
gr-qtgui/src/lib/Makefile \
gr-qtgui/src/python/Makefile \
diff --git a/gr-qtgui/Makefile.am b/gr-qtgui/Makefile.am
index 66746e5e8..30b249589 100644
--- a/gr-qtgui/Makefile.am
+++ b/gr-qtgui/Makefile.am
@@ -26,5 +26,4 @@ DIST_SUBDIRS = src
if PYTHON
SUBDIRS += grc
-SUBDIRS += python
endif
diff --git a/gr-qtgui/grc/Makefile.am b/gr-qtgui/grc/Makefile.am
index 226e9d137..132d1a2e0 100644
--- a/gr-qtgui/grc/Makefile.am
+++ b/gr-qtgui/grc/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2010 Free Software Foundation, Inc.
+# Copyright 2010-2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -25,4 +25,5 @@ grcblocksdir = $(grc_blocksdir)
dist_grcblocks_DATA = \
qtgui_sink_x.xml \
+ qtgui_tab_widget.xml \
qtgui_variable_slider.xml
diff --git a/gr-qtgui/grc/qtgui_sink_x.xml b/gr-qtgui/grc/qtgui_sink_x.xml
index 8182f8d94..6e5c9549b 100644
--- a/gr-qtgui/grc/qtgui_sink_x.xml
+++ b/gr-qtgui/grc/qtgui_sink_x.xml
@@ -8,10 +8,12 @@
<name>QT GUI Sink</name>
<key>qtgui_sink_x</key>
<category>Graphical Sinks</category>
+ <import>from PyQt4 import Qt</import>
<import>from gnuradio.qtgui import qtgui</import>
<import>from gnuradio.gr import firdes</import>
<import>import sip</import>
- <make>qtgui.$(type.fcn)(
+ <make>#set $win = 'self._%s_win'%$id
+qtgui.$(type.fcn)(
$fftsize, \#fftsize
$wintype, \#wintype
$fc, \#fc
@@ -23,8 +25,8 @@
$plottime, \#plottime
$plotconst, \#plotconst
)
-self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), QtGui.QWidget)
-self.layout.addWidget(self._$(id)_win)</make>
+self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget)
+$(gui_hint()($win))</make>
<callback>set_frequency_range($fc, $bw)</callback>
<param>
<name>Type</name>
@@ -114,11 +116,21 @@ self.layout.addWidget(self._$(id)_win)</make>
<option><name>On</name><key>True</key></option>
<option><name>Off</name><key>False</key></option>
</param>
+ <param>
+ <name>GUI Hint</name>
+ <key>gui_hint</key>
+ <value></value>
+ <type>gui_hint</type>
+ <hide>part</hide>
+ </param>
<sink>
<name>in</name>
<type>$type</type>
<nports>$num_inputs</nports>
</sink>
<doc>
+The GUI hint can be used to position the widget within the application. \
+The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. \
+Both the tab specification and the grid position are optional.
</doc>
</block>
diff --git a/gr-qtgui/grc/qtgui_tab_widget.xml b/gr-qtgui/grc/qtgui_tab_widget.xml
new file mode 100644
index 000000000..66597b454
--- /dev/null
+++ b/gr-qtgui/grc/qtgui_tab_widget.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##WX GUI Notebook
+###################################################
+ -->
+<block>
+ <name>QT GUI Tab Widget</name>
+ <key>qtgui_tab_widget</key>
+ <import>from PyQt4 import Qt</import>
+ <make>#set $win = 'self.%s'%$id
+$win = Qt.QTabWidget(None)
+#for i, label in enumerate([$label0, $label1, $label2, $label3, $label4])
+#if int($num_tabs()) > $i
+self.$(id)_widget_$(i) = Qt.QWidget()
+self.$(id)_layout_$(i) = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.$(id)_widget_$(i))
+self.$(id)_grid_layout_$(i) = Qt.QGridLayout()
+self.$(id)_layout_$(i).addLayout(self.$(id)_grid_layout_$(i))
+$(win).addTab(self.$(id)_widget_$(i), $label)
+#end if
+#end for
+$(gui_hint()($win))</make>
+ <param>
+ <name>Num Tabs</name>
+ <key>num_tabs</key>
+ <value>1</value>
+ <type>enum</type>
+ <option><name>1</name><key>1</key></option>
+ <option><name>2</name><key>2</key></option>
+ <option><name>3</name><key>3</key></option>
+ <option><name>4</name><key>4</key></option>
+ <option><name>5</name><key>5</key></option>
+ </param>
+ <param>
+ <name>Label 0</name>
+ <key>label0</key>
+ <value>Tab 0</value>
+ <type>string</type>
+ <hide>#if int($num_tabs()) > 0 then 'none' else 'all'#</hide>
+ </param>
+ <param>
+ <name>Label 1</name>
+ <key>label1</key>
+ <value>Tab 1</value>
+ <type>string</type>
+ <hide>#if int($num_tabs()) > 1 then 'none' else 'all'#</hide>
+ </param>
+ <param>
+ <name>Label 2</name>
+ <key>label2</key>
+ <value>Tab 2</value>
+ <type>string</type>
+ <hide>#if int($num_tabs()) > 2 then 'none' else 'all'#</hide>
+ </param>
+ <param>
+ <name>Label 3</name>
+ <key>label3</key>
+ <value>Tab 3</value>
+ <type>string</type>
+ <hide>#if int($num_tabs()) > 3 then 'none' else 'all'#</hide>
+ </param>
+ <param>
+ <name>Label 4</name>
+ <key>label4</key>
+ <value>Tab 4</value>
+ <type>string</type>
+ <hide>#if int($num_tabs()) > 4 then 'none' else 'all'#</hide>
+ </param>
+ <param>
+ <name>GUI Hint</name>
+ <key>gui_hint</key>
+ <value></value>
+ <type>gui_hint</type>
+ <hide>part</hide>
+ </param>
+ <doc>
+This block creates a tabbed widget to organize other widgets. \
+The ID of this block can be used as the tab_id in the GUI hints of other widgets.
+
+The GUI hint can be used to position the widget within the application. \
+The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. \
+Both the tab specification and the grid position are optional.
+ </doc>
+</block>
diff --git a/gr-qtgui/grc/qtgui_variable_slider.xml b/gr-qtgui/grc/qtgui_variable_slider.xml
index 5587fdc27..239d90903 100644
--- a/gr-qtgui/grc/qtgui_variable_slider.xml
+++ b/gr-qtgui/grc/qtgui_variable_slider.xml
@@ -6,35 +6,35 @@
###################################################
-->
<block>
- <name>QT GUI Variable Slider</name>
+ <name>QT GUI Slider</name>
<key>variable_qtgui_slider</key>
<category>Variables</category>
<import>from PyQt4 import Qt</import>
<import>import PyQt4.Qwt5 as Qwt</import>
<var_make>self.$(id) = $(id) = $value</var_make>
- <make>#set $win = '_%s_sizer'%$id
+ <make>#set $win = '_%s_layout'%$id
$win = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom)
self._$(id)_tool_bar = Qt.QToolBar(self)
$(win).addWidget(self._$(id)_tool_bar)
#if $label()
-self._$(id)_tool_bar.addWidget(Qt.QLabel($label, self._$(id)_tool_bar))
+self._$(id)_tool_bar.addWidget(Qt.QLabel($label, None))
#else
-self._$(id)_tool_bar.addWidget(Qt.QLabel($id, self._$(id)_tool_bar))
+self._$(id)_tool_bar.addWidget(Qt.QLabel($id, None))
#end if
-self._$(id)_counter = Qwt.QwtCounter(self._$(id)_tool_bar)
+self._$(id)_counter = Qwt.QwtCounter(None)
self._$(id)_counter.setRange($start, $stop, $step)
self._$(id)_counter.setNumButtons(2)
self._$(id)_counter.setValue($value)
self._$(id)_tool_bar.addWidget(self._$(id)_counter)
-$(win).connect(self._$(id)_counter, Qt.SIGNAL('valueChanged(double)'), self.set_$(id))
-self._$(id)_slider = Qwt.QwtSlider(self._$(id)_tool_bar)
+self._$(id)_counter.valueChanged.connect(self.set_$(id))
+self._$(id)_slider = Qwt.QwtSlider(None)
self._$(id)_slider.setRange($start, $stop, $step)
self._$(id)_slider.setValue($value)
self._$(id)_slider.setOrientation(Qt.$orient)
self._$(id)_slider.setScalePosition($orient.scalepos)
-$(win).connect(self._$(id)_slider, Qt.SIGNAL('valueChanged(double)'), self.set_$(id))
+self._$(id)_slider.valueChanged.connect(self.set_$(id))
$(win).addWidget(self._$(id)_slider)
-self.layout.addLayout($win)</make>
+$(gui_hint()($win))</make>
<callback>self.set_$(id)($value)</callback>
<callback>self._$(id)_counter.setValue($id)</callback>
<callback>self._$(id)_slider.setValue($id)</callback>
@@ -68,7 +68,6 @@ self.layout.addLayout($win)</make>
<key>step</key>
<value>1</value>
<type>real</type>
- <hide>part</hide>
</param>
<param>
<name>Orientation</name>
@@ -87,6 +86,13 @@ self.layout.addLayout($win)</make>
<opt>scalepos:Qwt.QwtSlider.RightScale</opt>
</option>
</param>
+ <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>
<doc>
@@ -94,5 +100,9 @@ This block creates a variable with a slider. \
Leave the label blank to use the variable id as the label. \
The value must be a real number. \
The value must be between the start and the stop.
+
+The GUI hint can be used to position the widget within the application. \
+The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. \
+Both the tab specification and the grid position are optional.
</doc>
</block>
diff --git a/grc/blocks/options.xml b/grc/blocks/options.xml
index 62ceeba0f..ed4d3c1d8 100644
--- a/grc/blocks/options.xml
+++ b/grc/blocks/options.xml
@@ -16,7 +16,7 @@ from grc_gnuradio import wxgui as grc_wxgui
import wx
#end if
#if $generate_options() == 'qt_gui'
-from PyQt4 import QtGui
+from PyQt4 import Qt
import sys
#end if
#if $generate_options() != 'hb'
diff --git a/grc/python/Generator.py b/grc/python/Generator.py
index d53802bef..7d08b914b 100644
--- a/grc/python/Generator.py
+++ b/grc/python/Generator.py
@@ -100,6 +100,10 @@ Add a Misc->Throttle block to your flow graph to avoid CPU congestion.''')
filter(lambda b: b.get_key() == 'notebook', blocks),
lambda n: n.get_id(), lambda n: n.get_param('notebook').get_value(),
)
+ notebooks += expr_utils.sort_objects(
+ filter(lambda b: b.get_key() == 'qtgui_tab_widget', blocks),
+ lambda n: n.get_id(), lambda n: n.get_param('gui_hint').get_value(),
+ )
#list of regular blocks (all blocks minus the special ones)
blocks = filter(lambda b: b not in (imports + parameters + variables + probes + notebooks), blocks) + probes
#list of connections where each endpoint is enabled
diff --git a/grc/python/Param.py b/grc/python/Param.py
index 6dd008d1d..27258faab 100644
--- a/grc/python/Param.py
+++ b/grc/python/Param.py
@@ -99,7 +99,7 @@ class Param(_Param, _GUIParam):
'hex', 'string', 'bool',
'file_open', 'file_save',
'id', 'stream_id',
- 'grid_pos', 'notebook',
+ 'grid_pos', 'notebook', 'gui_hint',
'import',
)
@@ -354,6 +354,29 @@ class Param(_Param, _GUIParam):
except: raise Exception, 'Stream ID "%s" is not found.'%v
return v
#########################
+ # GUI Position/Hint
+ #########################
+ elif t == 'gui_hint':
+ if ':' in v: tab, pos = v.split(':')
+ elif '@' in v: tab, pos = v, ''
+ else: tab, pos = '', v
+
+ if '@' in tab: tab, index = tab.split('@')
+ else: index = '?'
+
+ widget_str = ({
+ (True, True): 'self.%(tab)s_grid_layout_%(index)s.addWidget(%(widget)s, %(pos)s)',
+ (True, False): 'self.%(tab)s_layout_%(index)s.addWidget(%(widget)s)',
+ (False, True): 'self.top_grid_layout.addWidget(%(widget)s, %(pos)s)',
+ (False, False): 'self.top_layout.addWidget(%(widget)s)',
+ }[bool(tab), bool(pos)])%{'tab': tab, 'index': index, 'widget': '%s', 'pos': pos}
+
+ def gui_hint(ws, w):
+ if 'layout' in w: ws = ws.replace('addWidget', 'addLayout')
+ return ws%w
+
+ return lambda w: gui_hint(widget_str, w)
+ #########################
# Grid Position Type
#########################
elif t == 'grid_pos':
diff --git a/grc/python/flow_graph.tmpl b/grc/python/flow_graph.tmpl
index 108e15ca0..88049a9ef 100644
--- a/grc/python/flow_graph.tmpl
+++ b/grc/python/flow_graph.tmpl
@@ -60,12 +60,14 @@ class $(class_name)(grc_wxgui.top_block_gui):
self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY))
#end if
#elif $generate_options == 'qt_gui'
-class $(class_name)(gr.top_block, QtGui.QWidget):
+class $(class_name)(gr.top_block, Qt.QWidget):
def __init__($param_str):
gr.top_block.__init__(self, "$title")
- QtGui.QWidget.__init__(self)
- self.layout = QtGui.QBoxLayout(QtGui.QBoxLayout.TopToBottom, self)
+ Qt.QWidget.__init__(self)
+ self.top_layout = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self)
+ self.top_grid_layout = Qt.QGridLayout()
+ self.top_layout.addLayout(self.top_grid_layout)
#elif $generate_options == 'no_gui'
class $(class_name)(gr.top_block):
@@ -203,6 +205,9 @@ self.$port.get_parent().get_id()#slurp
########################################################
#for $var in $parameters + $variables
#set $id = $var.get_id()
+ def get_$(id)(self):
+ return self.$id
+
def set_$(id)(self, $id):
self.$id = $id
#for $callback in $var_id2cbs[$id]
@@ -250,7 +255,7 @@ if __name__ == '__main__':
tb = $(class_name)($(', '.join($params_eq_list)))
tb.Run($flow_graph.get_option('run'))
#elif $generate_options == 'qt_gui'
- qapp = QtGui.QApplication(sys.argv)
+ qapp = Qt.QApplication(sys.argv)
tb = $(class_name)($(', '.join($params_eq_list)))
tb.start()
tb.show()